'''
Created on 12-Jul-2021

@author: bthakur
'''
import random
import inspect
import traceback   #        {inspect.stack()[0][3]}

from sympy import (Eq, symbols, sqrt, latex,
                   Rational, solve, log, nsimplify, E, exp,  
                   sin, cos, I, series, pi)
import sympy

from xv.km.util import latex_fraction, latex_exponent

from .modelling import (ModellingPercentageHelper,
                        ModellingLcmHelper,
                        ModellingSingleVariableHelper,
                        ModellingAssortedHelper,
                        ModellingTwoVariableHelper,
                        ModellingTwoDigitsHelper, 
                        ModellingMultiVariableHelper,
                        ModellingJuiceBusinessHelper,
                        ModellingLayeredBusinessHelper
                        )
# _modelling_helper

from xv.util import UtilClass

class ModellingHelper(UtilClass):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        pass

    def get_random_model(self, mod_class_name = None, **kwargs):
        '''
        mod_class_name = Modeling helper class
        '''
        self._log(f"Starting {self.__class__.__name__}.{inspect.stack()[0][3]} ...")
             
        
        mod_class = self.get_modelling_class(mod_class_name)
        if mod_class is None:
            return None
            
        self._log(f"Calling modelling class {mod_class.__name__}")
        mod_helper = mod_class(verbose = self.verbose)
        return mod_helper.get_random_model(**kwargs)
        pass
    

    def get_modelling_class(self, mod_class_name = None):
        modelling_class_dict = self.get_modelling_class_dict()
        mod_class = modelling_class_dict.get(mod_class_name, None)

        if mod_class is None:
            sError = f"""Error {self.__class__.__name__}.{inspect.stack()[0][3]}:
            Failed to get mod_class = {mod_class_name}
            """
            self._log(sError)
            return random.choice(list(modelling_class_dict.values()))
        
        return mod_class
        pass

    def get_modelling_class_dict(self):
        modelling_class_dict = {
                    "ModellingSingleVariableHelper": ModellingSingleVariableHelper,
                    "ModellingAssortedHelper": ModellingAssortedHelper,
                    "ModellingPercentageHelper": ModellingPercentageHelper,
                    "ModellingLcmHelper": ModellingLcmHelper,
                    "ModellingTwoVariableHelper": ModellingTwoVariableHelper,
                    "ModellingTwoDigitsHelper": ModellingTwoDigitsHelper,
                    "ModellingMultiVariableHelper": ModellingMultiVariableHelper,
                    "ModellingJuiceBusinessHelper": ModellingJuiceBusinessHelper,
                    "ModellingLayeredBusinessHelper": ModellingLayeredBusinessHelper
                    }
        return modelling_class_dict
    
    
    def var_names_to_str(self, var_names, var_vals = None):
        s = []
        for name, label in var_names.items():
            if var_vals is None:
                s.append(f"${latex(name)}$ = {label}")
                continue

            v = var_vals.get(name, None)
            if v is None:
                s.append(f"${latex(name)}$ = {label}")
                continue
                
            s.append(f"${latex(name)}$ = {label} = {v}")
            pass
            
        return "\n".join(s)
        pass

    def solution_to_str(self, var_names, var_vals):
        s = []
        for name, v in var_vals.items():
            label = var_names.get(name, None)
            if label is None:
                s.append(f"${latex(name)}$ = {v}")
                continue
                
            s.append(f"${latex(name)}$ = {label} = {v}")
            pass
            
        return "\n".join(s)
        pass

    def var_vals_to_str(self, var_vals):
        s = []
        for name, v in var_vals.items():
            s.append(f"${latex(name)}$ = {v}")
            
        return "\n".join(s)
        pass
    
    def _log_DELETED(self, sOut, to_print = None):
        if to_print is None:
            to_print = self.verbose
            
        if to_print:
            print(sOut)
    
    pass
#class ModellingHelper:
