"""Tests for the path validation module at pptx_mcp/utils/paths.py."""

from __future__ import annotations

from pathlib import Path

import pytest

from pptx_mcp.utils.errors import PathValidationError
from pptx_mcp.utils.paths import (
    MAX_PATH_LENGTH,
    validate_config_path,
    validate_image_path,
    validate_output_path,
    validate_pptx_input,
    validate_template_path,
)


class TestValidateOutputPath:
    """Tests for validate_output_path."""

    def test_valid_pptx_extension(self, tmp_path: Path) -> None:
        path = tmp_path / "output.pptx"
        result = validate_output_path(path)
        assert result.suffix == ".pptx"
        assert result.is_absolute()

    def test_valid_pptx_uppercase_extension(self, tmp_path: Path) -> None:
        path = tmp_path / "output.PPTX"
        result = validate_output_path(path)
        assert result.is_absolute()

    def test_wrong_extension_txt(self, tmp_path: Path) -> None:
        with pytest.raises(PathValidationError, match="must have a .pptx extension"):
            validate_output_path(tmp_path / "output.txt")

    def test_wrong_extension_pdf(self, tmp_path: Path) -> None:
        with pytest.raises(PathValidationError, match="must have a .pptx extension"):
            validate_output_path(tmp_path / "output.pdf")

    def test_no_extension(self, tmp_path: Path) -> None:
        with pytest.raises(PathValidationError, match="must have a .pptx extension"):
            validate_output_path(tmp_path / "output")

    def test_overly_long_path(self, tmp_path: Path) -> None:
        long_name = "a" * (MAX_PATH_LENGTH + 100) + ".pptx"
        with pytest.raises(PathValidationError, match="exceeds maximum length"):
            validate_output_path(tmp_path / long_name)

    def test_accepts_string_path(self, tmp_path: Path) -> None:
        path_str = str(tmp_path / "output.pptx")
        result = validate_output_path(path_str)
        assert result.suffix == ".pptx"


class TestValidatePptxInput:
    """Tests for validate_pptx_input."""

    def test_valid_existing_pptx(self, tmp_path: Path) -> None:
        pptx_file = tmp_path / "test.pptx"
        pptx_file.write_bytes(b"fake pptx content")
        result = validate_pptx_input(pptx_file)
        assert result.exists()
        assert result.suffix == ".pptx"

    def test_nonexistent_file(self, tmp_path: Path) -> None:
        with pytest.raises(PathValidationError, match="File not found"):
            validate_pptx_input(tmp_path / "nonexistent.pptx")

    def test_wrong_extension(self, tmp_path: Path) -> None:
        txt_file = tmp_path / "test.txt"
        txt_file.write_text("not a pptx")
        with pytest.raises(PathValidationError, match="Unsupported file type"):
            validate_pptx_input(txt_file)

    def test_directory_instead_of_file(self, tmp_path: Path) -> None:
        sub_dir = tmp_path / "subdir.pptx"
        sub_dir.mkdir()
        with pytest.raises(PathValidationError, match="not a file"):
            validate_pptx_input(sub_dir)


class TestValidateConfigPath:
    """Tests for validate_config_path."""

    def test_valid_yaml(self, tmp_path: Path) -> None:
        yaml_file = tmp_path / "brand.yaml"
        yaml_file.write_text("name: test")
        result = validate_config_path(yaml_file)
        assert result.suffix == ".yaml"

    def test_valid_yml(self, tmp_path: Path) -> None:
        yml_file = tmp_path / "brand.yml"
        yml_file.write_text("name: test")
        result = validate_config_path(yml_file)
        assert result.suffix == ".yml"

    def test_valid_json(self, tmp_path: Path) -> None:
        json_file = tmp_path / "brand.json"
        json_file.write_text('{"name": "test"}')
        result = validate_config_path(json_file)
        assert result.suffix == ".json"

    def test_wrong_extension_txt(self, tmp_path: Path) -> None:
        txt_file = tmp_path / "brand.txt"
        txt_file.write_text("not a config")
        with pytest.raises(PathValidationError, match="Unsupported file type"):
            validate_config_path(txt_file)

    def test_wrong_extension_pptx(self, tmp_path: Path) -> None:
        pptx_file = tmp_path / "brand.pptx"
        pptx_file.write_bytes(b"fake")
        with pytest.raises(PathValidationError, match="Unsupported file type"):
            validate_config_path(pptx_file)


class TestValidateImagePath:
    """Tests for validate_image_path."""

    def test_valid_png(self, tmp_path: Path) -> None:
        img = tmp_path / "logo.png"
        img.write_bytes(b"fake png")
        result = validate_image_path(img)
        assert result.suffix == ".png"

    def test_valid_jpg(self, tmp_path: Path) -> None:
        img = tmp_path / "photo.jpg"
        img.write_bytes(b"fake jpg")
        result = validate_image_path(img)
        assert result.suffix == ".jpg"

    def test_valid_gif(self, tmp_path: Path) -> None:
        img = tmp_path / "anim.gif"
        img.write_bytes(b"fake gif")
        result = validate_image_path(img)
        assert result.suffix == ".gif"

    def test_valid_jpeg(self, tmp_path: Path) -> None:
        img = tmp_path / "photo.jpeg"
        img.write_bytes(b"fake jpeg")
        result = validate_image_path(img)
        assert result.suffix == ".jpeg"

    def test_wrong_extension_py(self, tmp_path: Path) -> None:
        py_file = tmp_path / "script.py"
        py_file.write_text("print('hello')")
        with pytest.raises(PathValidationError, match="Unsupported file type"):
            validate_image_path(py_file)

    def test_wrong_extension_txt(self, tmp_path: Path) -> None:
        txt_file = tmp_path / "notes.txt"
        txt_file.write_text("hello")
        with pytest.raises(PathValidationError, match="Unsupported file type"):
            validate_image_path(txt_file)


class TestValidateTemplatePath:
    """Tests for validate_template_path."""

    def test_valid_pptx_template(self, tmp_path: Path) -> None:
        tpl = tmp_path / "template.pptx"
        tpl.write_bytes(b"fake pptx template")
        result = validate_template_path(tpl)
        assert result.suffix == ".pptx"

    def test_wrong_extension_potx(self, tmp_path: Path) -> None:
        potx = tmp_path / "template.potx"
        potx.write_bytes(b"fake potx")
        with pytest.raises(PathValidationError, match="Unsupported file type"):
            validate_template_path(potx)

    def test_wrong_extension_pdf(self, tmp_path: Path) -> None:
        pdf = tmp_path / "template.pdf"
        pdf.write_bytes(b"fake pdf")
        with pytest.raises(PathValidationError, match="Unsupported file type"):
            validate_template_path(pdf)
