"""Unit tests for IWFMSimulationReader and CompleteModelLoader.

Tests:
- IWFMSimulationReader: positional format reading
- SimulationReader: new IWFM keyword handling
- CompleteModelLoader: model loading orchestration
- read_iwfm_simulation convenience function
"""

from __future__ import annotations

from datetime import datetime
from pathlib import Path
from unittest.mock import MagicMock

import pytest

from pyiwfm.core.timeseries import TimeUnit
from pyiwfm.io.model_loader import (
    CompleteModelLoader,
    ModelLoadResult,
)
from pyiwfm.io.simulation import (
    IWFMSimulationReader,
    SimulationConfig,
    SimulationReader,
    _parse_iwfm_datetime,
    read_iwfm_simulation,
)

# =============================================================================
# Test _parse_iwfm_datetime helper
# =============================================================================


class TestParseIWFMDatetime:
    """Tests for the module-level _parse_iwfm_datetime helper."""

    def test_datetime_with_underscore(self) -> None:
        dt = _parse_iwfm_datetime("09/30/1974_24:00")
        assert dt == datetime(1974, 10, 1, 0, 0, 0)

    def test_datetime_with_space(self) -> None:
        dt = _parse_iwfm_datetime("01/15/2020 12:30")
        assert dt == datetime(2020, 1, 15, 12, 30, 0)

    def test_datetime_no_time(self) -> None:
        dt = _parse_iwfm_datetime("06/14/2025_24:00")
        assert dt == datetime(2025, 6, 15)

    def test_datetime_hour_24(self) -> None:
        dt = _parse_iwfm_datetime("12/31/2020_24:00")
        assert dt == datetime(2021, 1, 1, 0, 0, 0)

    def test_datetime_no_seconds(self) -> None:
        dt = _parse_iwfm_datetime("09/30/2003_24:00")
        assert dt == datetime(2003, 10, 1)

    def test_datetime_invalid_raises(self) -> None:
        with pytest.raises(ValueError):
            _parse_iwfm_datetime("not-a-date")


# =============================================================================
# Test IWFMSimulationReader
# =============================================================================


class TestIWFMSimulationReader:
    """Tests for IWFMSimulationReader positional format."""

    def _write_c2vsimfg_style(self, tmp_path: Path) -> Path:
        """Write a C2VSimFG-style simulation main file."""
        sim_file = tmp_path / "sim_main.in"
        content = """C*******************************************************************************
C
C                  INTEGRATED WATER FLOW MODEL (IWFM)
C
C*******************************************************************************
C                        Titles Printed in the Output
C
C                          **********************
                                  C2VSimFG
                              Fine Grid Model
                                   v1.0
C                          **********************
C*****************************************************************************
C                            File Description
C
C-------------------------------------------------------------------------------
C    FILE NAME                                      DESCRIPTION
C---------------------------------------------------------------------------------------------
     PreProcessor.bin                                / 1: BINARY INPUT GENERATED BY PRE-PROCESSOR
     Groundwater\\GW_MAIN.dat                        / 2: GROUNDWATER COMPONENT MAIN FILE
     Streams\\Stream_MAIN.dat                        / 3: STREAM COMPONENT MAIN FILE
     Lakes\\Lake_MAIN.dat                            / 4: LAKE COMPONENT MAIN FILE
     RootZone\\RootZone_MAIN.dat                     / 5: ROOT ZONE COMPONENT MAIN FILE
                                                    / 6: SMALL WATERSHED COMPONENT MAIN FILE
                                                    / 7: UNSATURATED ZONE COMPONENT MAIN FILE
     IrigFrac.dat                                   / 8: IRRIGATION FRACTIONS DATA FILE
     SupplyAdjust.dat                               / 9: SUPPLY ADJUSTMENT SPECIFICATION DATA FILE
     Precip.dat                                     /10: PRECIPITATION DATA FILE
     ET.dat                                         /11: EVAPOTRANSPIRATION DATA FILE
C*******************************************************************************
C                         Model Simulation Period
C
C-------------------------------------------------------------------------------
        09/30/1974_24:00        / BDT
        0                       / RESTART
C-------------------------------------------------------------------------------
C                        Simulation Date and Time Tracked
C-------------------------------------------------------------------------------
        1MON                    / UNITT
        09/30/2003_24:00        / EDT
C***********************************************************************************
C                      Processing, Output and Debugging Options
C-------------------------------------------------------------------------------
    0                           / ISTRT
    1                           / KDEB
    500000                      / CACHE
C*******************************************************************************
C                           Solution Scheme Control
C-------------------------------------------------------------------------------
    2                           / MSOLVE
    1.0                         / RELAX
    1500                        / MXITER
    50                          / MXITERSP
    0.0001                      / STOPC
    0.001                       / STOPCVL
    0.001                       / STOPCSP
C*******************************************************************************
C                    Supply Adjustment Control Options
C-------------------------------------------------------------------------------
    11                          / KOPTDV
"""
        sim_file.write_text(content)
        return sim_file

    def test_read_c2vsimfg_style(self, tmp_path: Path) -> None:
        """Test reading a C2VSimFG-style simulation file."""
        sim_file = self._write_c2vsimfg_style(tmp_path)

        reader = IWFMSimulationReader()
        config = reader.read(sim_file, base_dir=tmp_path)

        # Title lines
        assert len(config.title_lines) == 3
        assert "C2VSimFG" in config.title_lines[0]
        assert "Fine Grid Model" in config.title_lines[1]

        # File paths
        assert config.binary_preprocessor_file is not None
        assert config.binary_preprocessor_file.name == "PreProcessor.bin"
        assert config.groundwater_file is not None
        assert "GW_MAIN.dat" in str(config.groundwater_file)
        assert config.streams_file is not None
        assert config.lakes_file is not None
        assert config.rootzone_file is not None
        assert config.small_watershed_file is None  # empty
        assert config.unsaturated_zone_file is None  # empty
        assert config.irrigation_fractions_file is not None
        assert config.supply_adjust_file is not None
        assert config.precipitation_file is not None
        assert config.et_file is not None

        # Dates
        assert config.start_date == datetime(1974, 10, 1, 0, 0, 0)
        assert config.end_date == datetime(2003, 10, 1, 0, 0, 0)

        # Time step
        assert config.time_step_length == 1
        assert config.time_step_unit == TimeUnit.MONTH

        # Restart flag
        assert config.restart_flag == 0

        # Processing options
        assert config.restart_output_flag == 0
        assert config.debug_flag == 1
        assert config.cache_size == 500000

        # Solver
        assert config.matrix_solver == 2
        assert config.relaxation == pytest.approx(1.0)
        assert config.max_iterations == 1500
        assert config.max_supply_iterations == 50
        assert config.convergence_tolerance == pytest.approx(0.0001)
        assert config.convergence_volume == pytest.approx(0.001)
        assert config.convergence_supply == pytest.approx(0.001)

        # Supply adjustment
        assert config.supply_adjust_option == 11

    def test_read_minimal_positional(self, tmp_path: Path) -> None:
        """Test reading a minimal positional simulation file."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Title Section
                                IWFM Test
                                Test Model
                                v1
C File Names
     PreProcessor.bin            / 1: BINARY
     GW.dat                      / 2: GW
                                 / 3: STREAMS
                                 / 4: LAKES
                                 / 5: ROOTZONE
                                 / 6: SMALL_WS
                                 / 7: UNSATZONE
                                 / 8: IRIG
                                 / 9: SUPPLY
                                 /10: PRECIP
                                 /11: ET
C Simulation Period
        01/01/2020_24:00        / BDT
        0                       / RESTART
        1DAY                    / UNITT
        12/31/2020_24:00        / EDT
C Processing
    0                           / ISTRT
    0                           / KDEB
    100000                      / CACHE
C Solver
    2                           / MSOLVE
    1.0                         / RELAX
    100                         / MXITER
    25                          / MXITERSP
    0.001                       / STOPC
    0.01                        / STOPCSP
C Supply
    0                           / KOPTDV
""")

        reader = IWFMSimulationReader()
        config = reader.read(sim_file, base_dir=tmp_path)

        assert config.title_lines[0].strip() == "IWFM Test"
        assert config.binary_preprocessor_file is not None
        assert config.groundwater_file is not None
        assert config.streams_file is None
        assert config.start_date == datetime(2020, 1, 2)
        assert config.end_date == datetime(2021, 1, 1)
        assert config.time_step_length == 1
        assert config.time_step_unit == TimeUnit.DAY
        assert config.max_iterations == 100
        assert config.convergence_supply == pytest.approx(0.01)

    def test_read_with_kc_file(self, tmp_path: Path) -> None:
        """Test reading with 12th file entry (crop coefficient file)."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Titles
                                Model Title 1
                                Model Title 2
                                Model Title 3
C Files
     PreProcessor.bin            / 1
     GW.dat                      / 2
                                 / 3
                                 / 4
                                 / 5
                                 / 6
                                 / 7
                                 / 8
                                 / 9
                                 / 10
                                 / 11
     KC.dat                      / 12
C Sim period
        01/01/2020_24:00        / BDT
        0                       / RESTART
        1MON                    / UNITT
        12/31/2020_24:00        / EDT
C Options
    0                           / ISTRT
    0                           / KDEB
    500000                      / CACHE
C Solver
    2                           / MSOLVE
    1.0                         / RELAX
    50                          / MXITER
    10                          / MXITERSP
    0.0001                      / STOPC
    0.001                       / STOPCSP
C Supply
    0                           / KOPTDV
""")

        reader = IWFMSimulationReader()
        config = reader.read(sim_file, base_dir=tmp_path)

        assert config.kc_file is not None
        assert config.kc_file.name == "KC.dat"
        assert config.start_date == datetime(2020, 1, 2)

    def test_convenience_function(self, tmp_path: Path) -> None:
        """Test read_iwfm_simulation convenience function."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Titles
                                Test
                                Model
                                v1
C Files
     pp.bin                      / 1
     gw.dat                      / 2
                                 / 3
                                 / 4
                                 / 5
                                 / 6
                                 / 7
                                 / 8
                                 / 9
                                 / 10
                                 / 11
C Sim
        01/01/2020_24:00        / BDT
        0                       / RESTART
        1DAY                    / UNITT
        01/31/2020_24:00        / EDT
C Opts
    0                           / ISTRT
    0                           / KDEB
    100                         / CACHE
C Solver
    1                           / MSOLVE
    0.5                         / RELAX
    50                          / MXITER
    10                          / MXITERSP
    0.01                        / STOPC
    0.1                         / STOPCSP
C Supply
    1                           / KOPTDV
""")

        config = read_iwfm_simulation(sim_file, base_dir=tmp_path)

        assert config.model_name == "Test"
        assert config.matrix_solver == 1
        assert config.relaxation == pytest.approx(0.5)
        assert config.supply_adjust_option == 1


# =============================================================================
# Test SimulationReader with new IWFM keywords
# =============================================================================


class TestSimulationReaderNewKeywords:
    """Tests for SimulationReader handling new IWFM description keywords."""

    def test_read_restart_flag(self, tmp_path: Path) -> None:
        """Test reading RESTART description."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Sim
TestModel                               / MODEL_NAME
1                                       / RESTART
""")

        reader = SimulationReader()
        config = reader.read(sim_file)
        assert config.restart_flag == 1

    def test_read_debug_flag(self, tmp_path: Path) -> None:
        """Test reading KDEB description."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Sim
TestModel                               / MODEL_NAME
1                                       / KDEB
""")

        reader = SimulationReader()
        config = reader.read(sim_file)
        assert config.debug_flag == 1

    def test_read_cache_size(self, tmp_path: Path) -> None:
        """Test reading CACHE description."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Sim
TestModel                               / MODEL_NAME
250000                                  / CACHE
""")

        reader = SimulationReader()
        config = reader.read(sim_file)
        assert config.cache_size == 250000

    def test_read_solver_params(self, tmp_path: Path) -> None:
        """Test reading solver parameters with IWFM keywords."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Sim
TestModel                               / MODEL_NAME
2                                       / MSOLVE
0.8                                     / RELAX
1500                                    / MXITER
75                                      / MXITERSP
0.0001                                  / STOPC
0.001                                   / STOPCVL
0.005                                   / STOPCSP
11                                      / KOPTDV
""")

        reader = SimulationReader()
        config = reader.read(sim_file)

        assert config.matrix_solver == 2
        assert config.relaxation == pytest.approx(0.8)
        assert config.max_iterations == 1500
        assert config.max_supply_iterations == 75
        assert config.convergence_tolerance == pytest.approx(0.0001)
        assert config.convergence_volume == pytest.approx(0.001)
        assert config.convergence_supply == pytest.approx(0.005)
        assert config.supply_adjust_option == 11

    def test_read_additional_file_paths(self, tmp_path: Path) -> None:
        """Test reading additional input file paths."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Sim
TestModel                               / MODEL_NAME
PreProcessor.bin                        / 1: BINARY PRE-PROCESSOR
IrigFrac.dat                            / 8: IRRIGATION FRACTIONS
SupplyAdj.dat                           / 9: SUPPLY ADJ
Precip.dat                              / PRECIP_DATA_FILE
ET.dat                                  / ET_DATA_FILE
KC.dat                                  / CROP_COEFFICIENT_FILE
""")

        reader = SimulationReader()
        config = reader.read(sim_file)

        assert config.binary_preprocessor_file == Path("PreProcessor.bin")
        assert config.irrigation_fractions_file == Path("IrigFrac.dat")
        assert config.supply_adjust_file == Path("SupplyAdj.dat")
        assert config.precipitation_file == Path("Precip.dat")
        assert config.et_file == Path("ET.dat")
        assert config.kc_file == Path("KC.dat")

    def test_read_numbered_descriptions(self, tmp_path: Path) -> None:
        """Test reading files with numbered descriptions like / 1:."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Sim
TestModel                               / MODEL_NAME
PreProcessor.bin                        / 1: BINARY INPUT
GW_MAIN.dat                            / 2: GROUNDWATER MAIN
Stream_MAIN.dat                        / 3: STREAM MAIN
Lake_MAIN.dat                          / 4: LAKE MAIN
RZ_MAIN.dat                            / 5: ROOT ZONE MAIN
SW_MAIN.dat                            / 6: SMALL WATERSHED
UZ_MAIN.dat                            / 7: UNSATURATED ZONE
""")

        reader = SimulationReader()
        config = reader.read(sim_file)

        assert config.binary_preprocessor_file == Path("PreProcessor.bin")
        assert config.groundwater_file == Path("GW_MAIN.dat")
        assert config.streams_file == Path("Stream_MAIN.dat")
        assert config.lakes_file == Path("Lake_MAIN.dat")
        assert config.rootzone_file == Path("RZ_MAIN.dat")
        assert config.small_watershed_file == Path("SW_MAIN.dat")
        assert config.unsaturated_zone_file == Path("UZ_MAIN.dat")


# =============================================================================
# Test SimulationConfig new fields
# =============================================================================


class TestSimulationConfigNewFields:
    """Tests for new SimulationConfig fields."""

    def test_default_new_fields(self) -> None:
        """Test default values for new fields."""
        config = SimulationConfig()

        assert config.title_lines == []
        assert config.restart_flag == 0
        assert config.binary_preprocessor_file is None
        assert config.irrigation_fractions_file is None
        assert config.supply_adjust_file is None
        assert config.precipitation_file is None
        assert config.et_file is None
        assert config.kc_file is None
        assert config.restart_output_flag == 0
        assert config.debug_flag == 0
        assert config.cache_size == 500000
        assert config.matrix_solver == 2
        assert config.relaxation == pytest.approx(1.0)
        assert config.max_supply_iterations == 50
        assert config.convergence_volume == pytest.approx(0.0)
        assert config.convergence_supply == pytest.approx(0.001)
        assert config.supply_adjust_option == 0

    def test_custom_new_fields(self) -> None:
        """Test setting custom values for new fields."""
        config = SimulationConfig(
            title_lines=["Title 1", "Title 2"],
            restart_flag=1,
            debug_flag=-1,
            cache_size=250000,
            matrix_solver=1,
            relaxation=0.5,
            max_supply_iterations=100,
            convergence_volume=1e-4,
            convergence_supply=1e-3,
            supply_adjust_option=11,
        )

        assert len(config.title_lines) == 2
        assert config.restart_flag == 1
        assert config.debug_flag == -1
        assert config.cache_size == 250000
        assert config.matrix_solver == 1
        assert config.relaxation == pytest.approx(0.5)
        assert config.max_supply_iterations == 100
        assert config.convergence_volume == pytest.approx(1e-4)
        assert config.convergence_supply == pytest.approx(1e-3)
        assert config.supply_adjust_option == 11

    def test_title_lines_independence(self) -> None:
        """Test that title_lines uses independent default list."""
        c1 = SimulationConfig()
        c2 = SimulationConfig()

        c1.title_lines.append("Title")
        assert len(c2.title_lines) == 0


# =============================================================================
# Test ModelLoadResult
# =============================================================================


class TestModelLoadResult:
    """Tests for ModelLoadResult dataclass."""

    def test_default_creation(self) -> None:
        result = ModelLoadResult()
        assert result.model is None
        assert result.simulation_config is None
        assert result.errors == {}
        assert result.warnings == []
        assert not result.success
        assert not result.has_errors

    def test_success_property(self) -> None:
        result = ModelLoadResult()
        result.model = MagicMock()
        assert result.success

    def test_has_errors_property(self) -> None:
        result = ModelLoadResult()
        result.errors["test"] = "some error"
        assert result.has_errors

    def test_no_errors(self) -> None:
        result = ModelLoadResult()
        assert not result.has_errors


# =============================================================================
# Test CompleteModelLoader
# =============================================================================


class TestCompleteModelLoader:
    """Tests for CompleteModelLoader class."""

    def test_init(self, tmp_path: Path) -> None:
        sim_file = tmp_path / "sim.in"
        pp_file = tmp_path / "pp.in"

        loader = CompleteModelLoader(sim_file, pp_file)

        assert loader.simulation_file == sim_file
        assert loader.preprocessor_file == pp_file
        assert loader.base_dir == tmp_path

    def test_init_without_preprocessor(self, tmp_path: Path) -> None:
        sim_file = tmp_path / "sim.in"

        loader = CompleteModelLoader(sim_file)

        assert loader.preprocessor_file is None

    def test_init_string_paths(self, tmp_path: Path) -> None:
        loader = CompleteModelLoader(
            str(tmp_path / "sim.in"),
            str(tmp_path / "pp.in"),
        )

        assert loader.simulation_file == tmp_path / "sim.in"
        assert loader.preprocessor_file == tmp_path / "pp.in"

    def test_load_no_sim_file(self, tmp_path: Path) -> None:
        """Test loading when simulation file doesn't exist."""
        loader = CompleteModelLoader(
            tmp_path / "nonexistent.in",
            tmp_path / "pp.in",
        )

        result = loader.load()

        assert not result.success
        assert "simulation" in result.errors

    def test_load_no_preprocessor(self, tmp_path: Path) -> None:
        """Test loading when no preprocessor file available."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Sim
TestModel                               / MODEL_NAME
1                                       / TIME_STEP_LENGTH
DAY                                     / TIME_STEP_UNIT
""")

        loader = CompleteModelLoader(sim_file)

        result = loader.load()

        assert not result.success
        assert "preprocessor" in result.errors

    def test_resolve_path_absolute(self, tmp_path: Path) -> None:
        loader = CompleteModelLoader(tmp_path / "sim.in")

        abs_path = tmp_path / "absolute" / "path.dat"
        result = loader._resolve_path(abs_path)
        assert result == abs_path

    def test_resolve_path_relative(self, tmp_path: Path) -> None:
        loader = CompleteModelLoader(tmp_path / "sim.in")

        result = loader._resolve_path("relative/path.dat")
        assert result == tmp_path / "relative/path.dat"

    def test_use_positional_format_true(self, tmp_path: Path) -> None:
        """Test forcing positional format."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Titles
                                Title1
                                Title2
                                Title3
C Files
     pp.bin                      / 1
     gw.dat                      / 2
                                 / 3
                                 / 4
                                 / 5
                                 / 6
                                 / 7
                                 / 8
                                 / 9
                                 /10
                                 /11
C Sim
        01/01/2020_24:00        / BDT
        0                       / RESTART
        1DAY                    / UNITT
        12/31/2020_24:00        / EDT
C Opts
    0                           / ISTRT
    0                           / KDEB
    100                         / CACHE
C Solver
    2                           / MSOLVE
    1.0                         / RELAX
    50                          / MXITER
    10                          / MXITERSP
    0.01                        / STOPC
    0.1                         / STOPCSP
C Supply
    0                           / KOPTDV
""")

        loader = CompleteModelLoader(
            sim_file,
            preprocessor_file=None,
            use_positional_format=True,
        )

        config = loader._read_simulation_config()

        assert config.title_lines[0].strip() == "Title1"
        assert config.groundwater_file is not None

    def test_use_description_format_false(self, tmp_path: Path) -> None:
        """Test forcing description-based format."""
        sim_file = tmp_path / "sim.in"
        sim_file.write_text("""C Sim
TestModel                               / MODEL_NAME
gw.dat                                  / GROUNDWATER_FILE
""")

        loader = CompleteModelLoader(
            sim_file,
            use_positional_format=False,
        )

        config = loader._read_simulation_config()
        assert config.model_name == "TestModel"
        assert config.groundwater_file == Path("gw.dat")


# =============================================================================
# Test Writer with new fields
# =============================================================================


class TestSimulationWriterNewFields:
    """Tests for SimulationWriter with new fields."""

    def test_write_processing_options(self, tmp_path: Path) -> None:
        """Test writing processing and debug options."""
        from pyiwfm.io.simulation import SimulationFileConfig, SimulationWriter

        file_config = SimulationFileConfig(output_dir=tmp_path)
        writer = SimulationWriter(file_config)
        config = SimulationConfig(
            debug_flag=1,
            cache_size=250000,
            restart_output_flag=1,
        )

        filepath = writer.write(config)
        content = filepath.read_text()

        assert "ISTRT" in content
        assert "KDEB" in content
        assert "CACHE" in content

    def test_write_full_solver_settings(self, tmp_path: Path) -> None:
        """Test writing complete solver settings."""
        from pyiwfm.io.simulation import SimulationFileConfig, SimulationWriter

        file_config = SimulationFileConfig(output_dir=tmp_path)
        writer = SimulationWriter(file_config)
        config = SimulationConfig(
            matrix_solver=2,
            relaxation=0.8,
            max_iterations=1500,
            max_supply_iterations=75,
            convergence_tolerance=0.0001,
            convergence_volume=0.001,
            convergence_supply=0.005,
        )

        filepath = writer.write(config)
        content = filepath.read_text()

        assert "MSOLVE" in content
        assert "RELAX" in content
        assert "MXITER" in content
        assert "MXITERSP" in content
        assert "STOPC" in content
        assert "STOPCVL" in content  # non-zero convergence_volume
        assert "STOPCSP" in content

    def test_write_no_stopcvl_when_zero(self, tmp_path: Path) -> None:
        """Test STOPCVL is omitted when convergence_volume is 0."""
        from pyiwfm.io.simulation import SimulationFileConfig, SimulationWriter

        file_config = SimulationFileConfig(output_dir=tmp_path)
        writer = SimulationWriter(file_config)
        config = SimulationConfig(convergence_volume=0.0)

        filepath = writer.write(config)
        content = filepath.read_text()

        assert "STOPCVL" not in content

    def test_write_supply_adjustment(self, tmp_path: Path) -> None:
        """Test writing supply adjustment option."""
        from pyiwfm.io.simulation import SimulationFileConfig, SimulationWriter

        file_config = SimulationFileConfig(output_dir=tmp_path)
        writer = SimulationWriter(file_config)
        config = SimulationConfig(supply_adjust_option=11)

        filepath = writer.write(config)
        content = filepath.read_text()

        assert "KOPTDV" in content
        assert "11" in content

    def test_write_additional_file_paths(self, tmp_path: Path) -> None:
        """Test writing additional input file paths."""
        from pyiwfm.io.simulation import SimulationFileConfig, SimulationWriter

        file_config = SimulationFileConfig(output_dir=tmp_path)
        writer = SimulationWriter(file_config)
        config = SimulationConfig(
            binary_preprocessor_file=Path("pp.bin"),
            irrigation_fractions_file=Path("irig.dat"),
            supply_adjust_file=Path("supply.dat"),
            precipitation_file=Path("precip.dat"),
            et_file=Path("et.dat"),
            kc_file=Path("kc.dat"),
        )

        filepath = writer.write(config)
        content = filepath.read_text()

        assert "pp.bin" in content
        assert "irig.dat" in content
        assert "supply.dat" in content
        assert "precip.dat" in content
        assert "et.dat" in content
        assert "kc.dat" in content
