"""Tests for ``arautopilot.core.actuator_config``."""

from __future__ import annotations

import pytest
from pydantic import ValidationError

from arautopilot.core.actuator_config import (
    ActuatorConfig,
    ActuatorType,
    is_phase_1,
)


def test_defaults_load_without_error() -> None:
    cfg = ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE)
    assert cfg.type is ActuatorType.HYDRAULIC_REVERSIBLE
    assert 0 < cfg.deadband_pct < 30
    assert cfg.max_rudder_angle_deg <= 45
    assert cfg.feedback_required is True


def test_phase_1_actuators_are_drivable() -> None:
    for t in (
        ActuatorType.HYDRAULIC_REVERSIBLE,
        ActuatorType.ELECTRIC_DC_REVERSIBLE,
        ActuatorType.SERVOMOTOR_FEEDBACK,
        ActuatorType.STERNDRIVE_ANALOG,
    ):
        assert is_phase_1(t) is True
        cfg = ActuatorConfig(type=t)
        assert cfg.is_phase_1_supported() is True


@pytest.mark.parametrize("t", [ActuatorType.VOLVO_IPS, ActuatorType.MERCURY_ZEUS])
def test_phase_3_actuators_are_modelled_but_not_phase_1(t: ActuatorType) -> None:
    assert is_phase_1(t) is False
    cfg = ActuatorConfig(type=t)
    assert cfg.is_phase_1_supported() is False


def test_rejects_max_angle_above_45() -> None:
    with pytest.raises(ValidationError):
        ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE, max_rudder_angle_deg=50.0)


def test_rejects_negative_max_rate() -> None:
    with pytest.raises(ValidationError):
        ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE, max_rate_dps=-1.0)


def test_min_useful_pwm_must_cover_deadband() -> None:
    """If the actuator needs >5 % to overcome static friction, the min useful PWM
    cannot be below the deadband — that combination would tell the controller
    'commands above 5 % move the rudder' while also 'commands below 8 % do
    nothing', which is internally inconsistent."""
    with pytest.raises(ValidationError):
        ActuatorConfig(
            type=ActuatorType.HYDRAULIC_REVERSIBLE,
            deadband_pct=8.0,
            min_useful_pwm_pct=5.0,
        )


def test_rejects_unknown_field() -> None:
    with pytest.raises(ValidationError):
        ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE, unknown=True)  # type: ignore[call-arg]


def test_asymmetry_bounds() -> None:
    with pytest.raises(ValidationError):
        ActuatorConfig(
            type=ActuatorType.HYDRAULIC_REVERSIBLE,
            asymmetry_stbd_over_port=0.1,
        )
    with pytest.raises(ValidationError):
        ActuatorConfig(
            type=ActuatorType.HYDRAULIC_REVERSIBLE,
            asymmetry_stbd_over_port=5.0,
        )
