import execjs
import json
from pydantic import BaseModel
from mat4py import savemat
import sys
import os

class mzDataStruct(BaseModel):
    metadata : dict
    times : list[float]
    series : dict

class mzDataReturn(BaseModel):
    mz : list[list[float]] = [[]]
    intensities : list[list[float]] = [[]]
    time : list[float] = []


def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

def mzMLread(fileName : str, formated : bool = False, customDirectory : str = ""):
    """
    Reads mzML files and returns the given object.\n
    Set the `formated` parameter to `True`if you want to get a Python object of the data.
        -> Default value : `False`
    """
    file = open(resource_path("script.js")).read()
    func = execjs.compile(file)
    result = func.call("mzMLread", fileName)
    if formated:
        x = json.loads(json.dumps(result))
        dataStruct = mzDataStruct(metadata=x["metadata"], times=x["times"], series=x["series"])
        returnStruct = mzDataReturn()
        totalMasseDataSet = []
        totalIntensityDataSet = []
        for i in dataStruct.series["ms"]["data"]:
            massesDataSet = []
            intensityDataSet = []
            for y in range(len(i[0])):
                massesDataSet.append(i[0][str(y)])
            for z in range(len(i[1])):
                intensityDataSet.append(i[1][str(z)])
            totalMasseDataSet.append(massesDataSet)
            totalIntensityDataSet.append(intensityDataSet)
        returnStruct.mz = totalMasseDataSet
        returnStruct.intensities = totalIntensityDataSet
        returnStruct.time = dataStruct.times
        file = fileName.split(".mzdata")[0]
        if customDirectory != "":
            file = file.rsplit("/", maxsplit=1)[1]
            name = ""
            if customDirectory.endswith("/"):
                name = f"{customDirectory}{file}.mat"
                try:
                    os.remove(name)
                except:
                    pass
                savemat(name, returnStruct.dict())
            else:
                name = f"{customDirectory}/{file}.mat"
                try:
                    os.remove(name)
                except:
                    pass
                savemat(name, returnStruct.dict())
        else:
            try:
                os.remove(file+".mat")
            except:
                pass
            savemat(file+".mat", dataStruct.dict())
    return
