# TODO: Тесты должны лежать в директории tests.

# TODO: Правило хорошего тона при оформлении импортов: сначала встроенные библиотеки,
#  через одну пустую строку - дополнительно установленные, и еще через одну пустую строку - собственные импорты.
from src.OptAlgorithm.OptAlgorithm import OptAlgorithm
from src.utils import read_json 

from matplotlib import pyplot as plt, use

from numpy import cos, sin, sqrt, cbrt, arcsin, linspace, array      
# TODO: Отступ перед блоком if __name__ == "__main__" - 2 пустых строки.
if __name__ == "__main__":
    # TODO: Что означают переменные ниже? Имена переменных должны быть осмысленными, чтобы их смысл был понятен не
    #  не только автору кода.
    tq = 1
    ts = linspace(0, tq, 200000)
    
    operator_params = read_json("../params/operator_params.json")
    system_params = read_json("../params/system_params.json")

    # TODO: 2 блока кода ниже (с циклами) нарушают принцип DRY (Don't Repeat Yourself):
    #  повторяющийся блок кода следует вынести в отдельную функцию.
    #  Например, в такую:
    #  def foo(params_dict: dict) -> dict:
    #      result_dict = {}
    #      i = 1
    #      for key, value in params_dict.items():
    #          if isinstance(value, list):
    #              result_dict[key] = value[i] if len(value) > i else value[0]
    #          else:
    #              result_dict[key] = value
    #      return result_dict
    #  И потом вызвать ее как-то так:
    #  non_array_operator_params, non_array_system_params = foo(operator_params), foo(system_params)

    non_array_operator_params = {}
    i = 1
    for key, value in operator_params.items():
        # TODO: Не совсем понятен смысл такой проверки. Если хотим проверить принадлежность value к list,
        #  то лучше использовать для этого isinstance.
        if hasattr(value, "__len__"):
            # TODO: Можно заменить однострочным выражением: result_dict[key] = value[i] if len(value) > i else value[0]
            if len(value) > i:
                non_array_operator_params[key] = value[i]
            else:
                non_array_operator_params[key] = value[0]
        else:
            non_array_operator_params[key] = value

    non_array_system_params = {}
    for key, value in system_params.items():
        if hasattr(value, "__len__"):
            if len(value) > i:
                non_array_system_params[key] = value[i]
            else:
                non_array_system_params[key] = value[0]
        else:
            non_array_system_params[key] = value

    
    opt = OptAlgorithm(non_array_operator_params, non_array_system_params)
    Xs = array([opt.getVar("X1", t) for t in ts])

    
    plt.plot(ts, Xs)
    plt.show()