import pytest

from parameters import CategoryParameter, RangeParameter, Parameter
from evaluator import EvaluatorSR
from problem import Problem
import optimizer
import numpy as np

from platypus.config import PlatypusConfig
import random


@pytest.fixture
def parameters():
    parameters = [
        Parameter(value_descriptor=CategoryParameter(list(range(80, 90))), name="1st"),
        Parameter(value_descriptor=CategoryParameter(list(range(80, 90))), name="2nd"),
        Parameter(value_descriptor=RangeParameter(3, 100), name="3rd"),
    ]
    return parameters


def mixed_types(vals):
    # helper function from the jupyter notebook
    vals = list(vals)
    num = vals.pop(-1)
    objectives = tuple(num % v for v in vals)
    return (objectives, ())


def test_mixed_type_parameters(parameters):
    """to make sure that we can use different parameter types in the same algorithms while still getting optimal outputs"""

    evaluator = EvaluatorSR(mixed_types, Problem(parameters, 2))
    random.seed(1)
    results = optimizer.EpsMOEA(evaluator, epsilons=10)

    value = results.iloc[0]["outputs_0"]
    print(value)
    assert np.isclose(value, 0.4451952793850751), f"Unexpected output: {value}"

    assert 1


def test_optimizer_customization(parameters):
    """testing the variator field while using mixed parameters"""

    evaluator = EvaluatorSR(mixed_types, Problem(parameters, 2))
    variator = optimizer.get_operator(evaluator.to_platypus())

    random.seed(2)
    results = optimizer.EpsMOEA(evaluator, variator=variator, epsilons=10)

    value = results.iloc[0]["outputs_1"]
    print(value)
    assert np.isclose(value, 0.4607928200940279), f"Unexpected output: {value}"

    assert 1
