"""Tests for the models module."""

from pathlib import Path

import pytest
from pydantic import ValidationError

from ai_forge.models import BuildConfig, BuildTarget


def test_build_target_creation() -> None:
    """Test BuildTarget model creation."""
    target = BuildTarget(
        name="test_target",
        output_path=Path("test/output.txt"),
        template_name="test.j2",
        data_builder="build_test_data",
    )

    assert target.name == "test_target"
    assert target.output_path == Path("test/output.txt")
    assert target.template_name == "test.j2"
    assert target.data_builder == "build_test_data"
    assert target.post_process is None


def test_build_target_with_post_process() -> None:
    """Test BuildTarget with post-processing function."""

    def custom_postprocess(content: str) -> str:
        return content.upper()

    target = BuildTarget(
        name="test_target",
        output_path=Path("test/output.txt"),
        template_name="test.j2",
        data_builder="build_test_data",
        post_process=custom_postprocess,
    )

    assert target.post_process is not None
    assert callable(target.post_process)
    assert target.post_process("hello") == "HELLO"


def test_build_config_creation() -> None:
    """Test BuildConfig model creation."""
    target1 = BuildTarget(
        name="target1",
        output_path=Path("output1.txt"),
        template_name="template1.j2",
        data_builder="build_data1",
    )

    target2 = BuildTarget(
        name="target2",
        output_path=Path("output2.txt"),
        template_name="template2.j2",
        data_builder="build_data2",
    )

    config = BuildConfig(
        targets=[target1, target2],
        output_base_dir=Path("custom_output"),
    )

    assert len(config.targets) == 2
    assert config.output_base_dir == Path("custom_output")
    assert config.targets[0].name == "target1"
    assert config.targets[1].name == "target2"


def test_build_config_default_output_dir() -> None:
    """Test BuildConfig with default output directory."""
    target = BuildTarget(
        name="test_target",
        output_path=Path("test.txt"),
        template_name="test.j2",
        data_builder="build_data",
    )

    config = BuildConfig(targets=[target])

    assert config.output_base_dir == Path("output")


def test_build_config_empty_targets() -> None:
    """Test BuildConfig with empty targets list."""
    config = BuildConfig(targets=[])

    assert len(config.targets) == 0
    assert config.output_base_dir == Path("output")


def test_build_target_path_types() -> None:
    """Test BuildTarget accepts different path types."""
    # Test with string path
    target1 = BuildTarget(
        name="target1",
        output_path=Path("string/path.txt"),
        template_name="test.j2",
        data_builder="build_data",
    )

    # Test with Path object
    target2 = BuildTarget(
        name="target2",
        output_path=Path("path/object.txt"),
        template_name="test.j2",
        data_builder="build_data",
    )

    assert isinstance(target1.output_path, Path)
    assert isinstance(target2.output_path, Path)


def test_build_config_validation() -> None:
    """Test BuildConfig validation."""
    # Valid config should work
    target = BuildTarget(
        name="test",
        output_path=Path("test.txt"),
        template_name="test.j2",
        data_builder="build_data",
    )

    config = BuildConfig(targets=[target])
    assert config.targets[0].name == "test"

    # Empty targets should still be valid
    empty_config = BuildConfig(targets=[])
    assert len(empty_config.targets) == 0


def test_build_target_required_fields() -> None:
    """Test that BuildTarget requires all necessary fields."""
    # All required fields present - should work
    target = BuildTarget(
        name="test",
        output_path=Path("test.txt"),
        template_name="test.j2",
        data_builder="build_data",
    )

    assert target.name == "test"

    # Missing fields should raise validation error
    with pytest.raises(ValidationError):
        BuildTarget(
            name="test",
            output_path=Path("test.txt"),
            # Missing template_name and data_builder
        )


def test_build_config_required_fields() -> None:
    """Test that BuildConfig requires targets field."""
    # Valid config
    config = BuildConfig(targets=[])
    assert isinstance(config.targets, list)

    # Missing targets should raise validation error
    with pytest.raises(ValidationError):
        BuildConfig()  # Missing required targets field
