import os
import sys
import warnings
if not sys.warnoptions:
    warnings.simplefilter("ignore")
import traceback
import hdf5storage
import numpy as np
from asammdf import MDF, Signal

# return value
RET_OK            = 0
RET_VAR_NOT_FOUND = 1
RET_EXCEPTION     = 2
RET_PARAMETER_ERR = 3

class TimeSignalList:
    def __init__(self, ATimeName, ASgnList):
        self.signal_list = ASgnList
        self.time_name = ATimeName
    def contains_signal(self, ASgnName):
        return ASgnName in self.signal_list

def internal_write(AMat, AName, AValue):
    AMat[AName] = AValue

# MDF2mat(r"C:\LC_Ramdisk\m.mf4", r"C:\LC_Ramdisk\m.mat")
def MDF2mat(AMDFFileName, AMatFileName, ACompression = "True"):
    print("mdf to mat conversion started on " + AMatFileName)
    mdf = MDF(AMDFFileName)
    matStrs = {}
    matData = {}
    time_list = []
    sgn_lists = []
    try:
        if os.path.exists(AMatFileName): 
            os.remove(AMatFileName) 
        for sig in mdf.iter_channels():
            # print('Sig repr', sig)
            # print('Samples and timestamps:', sig.samples, sig.timestamps)
            if sig.name == "Comment":
                internal_write(matStrs, sig.name, sig.comment)
                continue
            if sig.name == "MeasurementComments":
                internal_write(matStrs, sig.name, sig.comment)
                continue
            if sig.name == "DynamicComments":
                internal_write(matStrs, sig.name, sig.comment)
                continue
            if sig.name == "ECU_LIST":
                internal_write(matStrs, sig.name, sig.comment)
                continue
            if sig.name == "TIME_LIST":
                time_list = sig.comment.split(",")
                for i, s in enumerate(time_list):
                    time_list[i] = s + '_LIST'
                internal_write(matStrs, sig.name, sig.comment)
                continue
            if sig.name == "MeasurementStartTimeStr":
                internal_write(matStrs, sig.name, sig.comment)
                continue
            if sig.name == "MeasurementStopTimeStr":
                internal_write(matStrs, sig.name, sig.comment)
                continue
            if sig.name == "MeasurementStartTime":
                internal_write(matData, sig.name, np.array(sig.samples, dtype=np.float64))
                continue
            if sig.name == "MeasurementStopTime":
                internal_write(matData, sig.name, np.array(sig.samples, dtype=np.float64))
                continue
            if sig.name in time_list:
                sgn_lists.append(TimeSignalList("".join(sig.name.rsplit("_LIST", len(sig.name))), sig.comment.split(",")))
                internal_write(matStrs, sig.name, sig.comment)                
                continue
            # write each signal samples
            internal_write(matData, sig.name, np.array(sig.samples, dtype=np.float64))
            # write each signal timestamps once
            for sgn in sgn_lists:
                if sgn.contains_signal(sig.name):
                    internal_write(matData, sgn.time_name, np.array(sig.timestamps, dtype=np.float64))
                    sgn_lists.remove(sgn)
                    break
        return RET_OK
    except:
        traceback.print_exc()
        return RET_EXCEPTION
    finally:
        hdf5storage.savemat(AMatFileName, matStrs, format='7.3', oned_as='row', truncate_existing=True, store_python_metadata=True, matlab_compatible=True)
        hdf5storage.savemat(AMatFileName, matData, format='7.3', oned_as='column', truncate_existing=False, store_python_metadata=True, matlab_compatible=True)
        print("Saved: " + AMatFileName)
    
if __name__ == '__main__':
    if len(sys.argv) != 4:
        print("Parameter error")
        for i in range(0, len(sys.argv)):
            print("Parameter " + str(i) + ": " + sys.argv[i])
        sys.exit(RET_PARAMETER_ERR)
    else:
        sys.exit(MDF2mat(sys.argv[1], sys.argv[2], sys.argv[3]))
