#  Copyright 2026 European Union
#  Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
#  SPDX-License-Identifier: EUPL-1.2
"""Unit tests for the steering configuration / schema alignment."""

from __future__ import annotations

from unittest.mock import MagicMock

import pytest

# Skip this module if PySide6 is not available
pytest.importorskip('PySide6', reason='PySide6 is required for GUI tests')

from mafw.models.parameter_schema import ParameterSchema
from mafw.models.processor_schema import ProcessorSchema
from mafw.steering.builder import SteeringBuilder
from mafw.steering.models import ParameterSchemaStatus, ParameterSource, ProcessorSchemaStatus
from mafw.steering_gui.controllers.steering_controller import SteeringController

pytestmark = pytest.mark.gui


class MockProcessor:
    @classmethod
    def parameter_schema(cls) -> list[ParameterSchema]:
        return [
            ParameterSchema(name='p1', annotation=int, default=0, help='help1', is_list=False, is_dict=False),
            ParameterSchema(name='p2', annotation=str, default='def', help='help2', is_list=False, is_dict=False),
        ]

    @classmethod
    def filter_schema(cls) -> None:
        return None

    @classmethod
    def processor_schema(cls) -> ProcessorSchema:
        return ProcessorSchema(parameters=cls.parameter_schema(), filter=cls.filter_schema())


@pytest.fixture
def mock_plugins() -> MagicMock:
    plugins = MagicMock()
    plugins.processor_dict = {'MockProcessor': MockProcessor}
    return plugins


def test_alignment_ok_and_new_parameters(mock_plugins: MagicMock) -> None:
    builder = SteeringBuilder()
    builder.add_processor('MockProcessor')
    builder.set_parameter('MockProcessor', 'p1', 42)
    # p2 is missing in builder, should be added as NEW

    controller = SteeringController(builder)
    controller.plugins = mock_plugins

    pipeline = controller.build_pipeline()
    proc_item = pipeline.items[0]
    config = proc_item.config

    assert config.processor_status == ProcessorSchemaStatus.OK

    # p1 should be OK
    assert 'p1' in config.parameters
    assert config.parameters['p1'].value == 42
    assert config.parameters['p1'].status == ParameterSchemaStatus.OK
    assert config.parameters['p1'].source == ParameterSource.CONFIG
    assert config.parameters['p1'].help == 'help1'
    assert config.parameters['p1'].active_override is True

    # p2 should be NEW
    assert 'p2' in config.parameters
    assert config.parameters['p2'].value == 'def'
    assert config.parameters['p2'].status == ParameterSchemaStatus.NEW
    assert config.parameters['p2'].source == ParameterSource.DEFAULT
    assert config.parameters['p2'].help == 'help2'
    assert config.parameters['p2'].active_override is False


def test_alignment_deprecated_parameter(mock_plugins: MagicMock) -> None:
    builder = SteeringBuilder()
    builder.add_processor('MockProcessor')
    builder.set_parameter('MockProcessor', 'unknown_p', 'val')

    controller = SteeringController(builder)
    controller.plugins = mock_plugins

    pipeline = controller.build_pipeline()
    config = pipeline.items[0].config

    assert config.parameters['unknown_p'].status == ParameterSchemaStatus.DEPRECATED
    assert config.parameters['unknown_p'].value == 'val'
    assert config.parameters['unknown_p'].active_override is True


def test_alignment_unknown_processor(mock_plugins: MagicMock) -> None:
    builder = SteeringBuilder()
    builder.add_processor('UnknownProc')
    builder.set_parameter('UnknownProc', 'some_p', 1)

    controller = SteeringController(builder)
    controller.plugins = mock_plugins

    pipeline = controller.build_pipeline()
    config = pipeline.items[0].config

    assert config.processor_status == ProcessorSchemaStatus.UNKNOWN
    assert config.parameters['some_p'].status == ParameterSchemaStatus.UNKNOWN
    assert config.parameters['some_p'].active_override is True
