import shutil
from pathlib import Path
from unittest import mock

import pytest
from freezegun import freeze_time

from ..main import run


@pytest.fixture
def output_path(data_path: Path):
    path = data_path / "main" / "output"
    yield path
    shutil.rmtree(path, ignore_errors=True)


@mock.patch("generator.main.K8sOpenAPIExtractor.extract")
@mock.patch("generator.main.K8sOpenAPIParser.parse")
@freeze_time("2024-01-01")
def test_run(
    mock_parse: mock.MagicMock, mock_extract: mock.MagicMock, output_path: Path
):
    mock_extract.return_value = [Path("path/to/spec")]
    mock_parse.return_value = {
        ("path", "to", "spec"): mock.MagicMock(body="class Test: pass"),
        # Ensure empty directories are removed
        ("path", "empty", "directory", "__init__"): mock.MagicMock(body=""),
        # Ensure empty files are skipped
        ("path", "to", "empty_file.py"): mock.MagicMock(
            body="from __future__ import annotations"
        ),
    }

    with mock.patch(
        "generator.main.K8sOpenAPIExtractor.k8s_version", new_callable=mock.PropertyMock
    ) as mock_k8s_version:
        mock_k8s_version.return_value = "v1.30.0"
        run([
            "--output-path",
            str(output_path / "models"),
            "--specs-path",
            str(output_path / "specs"),
        ])

    assert (output_path / "models" / "to" / "spec.py").exists()
    assert not (output_path / "models" / "empty").exists()
    assert not (output_path / "models" / "to" / "empty_file.py").exists()

    with open(output_path / "models" / "to" / "spec.py") as f:
        expected_output = """# generated by datamodel-codegen:
#   timestamp: 2024-01-01T00:00:00+00:00
#   k8s version: v1.30.0

class Test: pass"""
        output = f.read()
        assert output == expected_output, (
            f"Expected output does not match\n\n"
            f"Expected:\n{expected_output}\n\n"
            f"Actual:\n{output}"
        )
