### Example for validation of a config file

# This example shows how to load and validate a user defined configuration file.
# We use the two configuration dictionaries.
# The first one represents a valid configuration, the second does not.

#### Necessary imports

from cattrs import ClassValidationError

from baybe import Campaign

#### Defining config dictionaries

# Note that the following explicit call `str()` is not strictly necessary.
# It is included since our method of converting this example to a markdown file does not
# interpret this part of the code as `python` code if we do not include this call.

CONFIG = str(
    """
{
    "parameters": [
        {
            "type": "CategoricalParameter",
            "name": "Granularity",
            "values": [
                "coarse",
                "fine",
                "ultra-fine"
            ],
            "encoding": "OHE"
        },
        {
            "type": "NumericalDiscreteParameter",
            "name": "Pressure[bar]",
            "values": [
                1,
                5,
                10
            ],
            "tolerance": 0.2
        },
        {
            "type": "SubstanceParameter",
            "name": "Solvent",
            "data": {
                "Solvent A": "COC",
                "Solvent B": "CCCCC",
                "Solvent C": "COCOC",
                "Solvent D": "CCOCCOCCN"
            },
            "decorrelate": true,
            "encoding": "MORDRED"
        }
    ],
    "constraints": [],
    "objective": {
        "mode": "SINGLE",
        "targets": [
            {
                "name": "Yield",
                "mode": "MAX"
            }
        ]
    },
    "strategy": {
        "type": "TwoPhaseStrategy",
        "initial_recommender": {
            "type": "FPSRecommender"
        },
        "recommender": {
            "type": "SequentialGreedyRecommender",
            "surrogate_model": {
                "type": "GaussianProcessSurrogate"
            },
            "acquisition_function_cls": "qEI"
        },
        "switch_after": 1,
        "allow_repeated_recommendations": false,
        "allow_recommending_already_measured": false
    }
}
"""
)

INVALID_CONFIG = str(
    """
{
    "parameters": [
        {
            "type": "INVALID_TYPE",
            "name": "Granularity",
            "values": [
                "coarse",
                "fine",
                "ultra-fine"
            ],
            "encoding": "OHE"
        },
        {
            "type": "NumericalDiscreteParameter",
            "name": "Pressure[bar]",
            "values": [
                1,
                5,
                10
            ],
            "tolerance": 0.2
        },
        {
            "type": "SubstanceParameter",
            "name": "Solvent",
            "data": {
                "Solvent A": "COC",
                "Solvent B": "CCCCC",
                "Solvent C": "COCOC",
                "Solvent D": "CCOCCOCCN"
            },
            "decorrelate": true,
            "encoding": "MORDRED"
        }
    ],
    "constraints": [],
    "objective": {
        "mode": "SINGLE",
        "targets": [
            {
                "name": "Yield",
                "mode": "MAX"
            }
        ]
    },
    "strategy": {
        "type": "TwoPhaseStrategy",
        "initial_recommender": {
            "type": "FPSRecommender"
        },
        "recommender": {
            "type": "SequentialGreedyRecommender",
            "surrogate_model": {
                "type": "GaussianProcessSurrogate"
            },
            "acquisition_function_cls": "qEI"
        },
        "allow_repeated_recommendations": false,
        "allow_recommending_already_measured": false
    }
}
"""
)

#### Verification of the two dictionaries

# The first validation should work
Campaign.validate_config(CONFIG)
print("The first config seems valid.")

# This should fail.
try:
    Campaign.validate_config(INVALID_CONFIG)
    campaign = Campaign.from_config(INVALID_CONFIG)
except ClassValidationError:
    print("Something is wrong with the second config, which is what we expected!")
