import numpy as np
from scipy import sparse as sp
from daal.data_management import (readOnly, NumericTableIface, BlockDescriptor, BlockDescriptor_Float32, BlockDescriptor_Intc, packed_mask)
from daal.data_management import (HomogenNumericTable, HomogenNumericTable_Float32, HomogenNumericTable_Intc, CSRNumericTable)

def isFull(layout):
    layout_int = int(layout)
    if packed_mask & layout_int:
        return False
    return True


def getArrayFromNumericTable(data_table):
    num_rows = data_table.getNumberOfRows()
    num_cols = data_table.getNumberOfColumns()
    layout = data_table.getDataLayout()
    data_table_dict = data_table.getDictionary()
    try:
        # see # https://software.intel.com/sites/products/documentation/doclib/daal/daal-user-and-reference-guides/daal_cpp_api/data__utils_8h_source.htm
        # for numeral values of types
        data_type = data_table_dict[0].indexType
    except:
        data_type = 1 # default to Float64

    if data_type == 0:
        block = BlockDescriptor_Float32()
    elif data_type in [2, 4, 6, 8]:
        block = BlockDescriptor_Intc()
    else:
        block = BlockDescriptor() # Use Float64 by default

    data_table.getBlockOfRows(0, num_rows, readOnly, block)
    retValue = block.getArray()
    data_table.releaseBlockOfRows(block)

    return retValue


def make_csr_table(X):
    if sp.isspmatrix_csr(X):
        indices = np.array([x+1 for x in X.indices], dtype=np.uint64)
        indptr =  np.array([x+1 for x in X.indptr], dtype=np.uint64)
        return CSRNumericTable(X.data, indices, indptr, X.shape[1], X.shape[0])
    return None


def make_HomogenNumericTable(X):
    X = np.ascontiguousarray(X)
    if X.dtype == np.float64:
        return HomogenNumericTable(X)
    elif X.dtype == np.float32:
        return HomogenNumericTable_Float32(X)
    elif X.dtype == np.intc:
        return HomogenNumericTable_Intc(X.astype(np.intc, copy=False))
    else:
        return HomogenNumericTable(X.astype(np.float64, copy=False))
    return None
