import ctypes
import numpy as np
import os

lib = ctypes.CDLL(os.path.abspath("libmatriz.so"))

lib.invert_from_file.argtypes = [
    ctypes.c_char_p,
    ctypes.c_int
]
lib.invert_from_file.restype = ctypes.POINTER(ctypes.c_float)

lib.invert_from_array.argtypes = [
    ctypes.POINTER(ctypes.c_float),
    ctypes.c_int
]
lib.invert_from_array.restype = ctypes.POINTER(ctypes.c_float)

lib.free_matrix_data.argtypes = ctypes.POINTER(ctypes.c_float)
lib.free_matrix_data.restype = None

def inv_from_file(path, size_matrix):

    ptr = lib.invert_from_file(path.encode(), size_matrix)
    if not ptr:
        raise RuntimeError("ERROR: Unable to compute inverse matrix.")

    try:
        arr = np.ctypeslib.as_array(ptr, shape=(size_matrix*size_matrix, ))
        return arr.reshape((size_matrix,size_matrix)).copy
    
    finally:
        lib.free_matrix_data(ptr)

def inv_from_array(origin_arr, size_matrix):
    ptr = lib.invert_from_array(origin_arr, size_matrix)
    if not ptr:
        raise RuntimeError("ERROR: Unable to compute inverse matrix.")

    try:
        arr = np.ctypeslib.as_array(ptr, shape=(size_matrix*size_matrix, ))
        return arr.reshape((size_matrix,size_matrix)).copy

    finally:
        lib.free_matrix_data(ptr)