"""Tests for service-layer prompt build/run APIs."""

import asyncio
from pathlib import Path
from textwrap import dedent

import pytest

from dotpromptz.errors import (
    ExecutionConfigError,
    InputResolutionError,
    InputVariableNamingError,
    TemplateMissingVariableError,
)
from dotpromptz.service import build_prompt, run_prompt
from dotpromptz.version import CURRENT_MAJOR


def test_build_missing_file_raises() -> None:
    with pytest.raises(InputResolutionError, match='Path does not exist'):
        build_prompt('/not/exist.prompt', log_dir=Path('/tmp'))


def test_build_resolves_inline_data_and_writes_yaml(tmp_path: Path) -> None:
    source = dedent(
        f"""
        ---
        version: {CURRENT_MAJOR}
        input:
          data:
            topic: AI
        ---
        :::user
        Hello {{{{ topic }}}}
    """
    ).strip()
    prompt_file = tmp_path / 'a.prompt'
    prompt_file.write_text(source, encoding='utf-8')

    report = build_prompt(prompt_file, log_dir=tmp_path)
    assert report.compiled.input_list == [{'topic': 'AI'}]
    assert report.output_file.exists()
    assert report.output_file.suffix == '.yaml'


def test_run_requires_output_config(tmp_path: Path) -> None:
    source = dedent(
        f"""
        ---
        version: {CURRENT_MAJOR}
        ---
        :::user
        hello
    """
    ).strip()
    prompt_file = tmp_path / 'c.prompt'
    prompt_file.write_text(source, encoding='utf-8')

    with pytest.raises(ExecutionConfigError, match='No output configuration'):
        asyncio.run(run_prompt(prompt_file, log_dir=tmp_path))


def test_build_raises_when_template_input_missing(tmp_path: Path) -> None:
    source = dedent(
        f"""
        ---
        version: {CURRENT_MAJOR}
        ---
        :::user
        hello {{{{ topic }}}}
        """
    ).strip()
    prompt_file = tmp_path / 'missing.prompt'
    prompt_file.write_text(source, encoding='utf-8')

    with pytest.raises(TemplateMissingVariableError, match='topic'):
        build_prompt(prompt_file, log_dir=tmp_path)


def test_build_rejects_uppercase_input_key(tmp_path: Path) -> None:
    source = dedent(
        f"""
        ---
        version: {CURRENT_MAJOR}
        input:
          data:
            TIME: "20250101_120000"
        ---
        :::user
        hi
        """
    ).strip()
    prompt_file = tmp_path / 'reserved.prompt'
    prompt_file.write_text(source, encoding='utf-8')

    with pytest.raises(InputVariableNamingError, match='TIME'):
        build_prompt(prompt_file, log_dir=tmp_path)
