"""Unit tests for auto-variable providers and render env injection."""

import json
from datetime import datetime
from pathlib import Path

import jinja2

from dotpromptz.autovars import (
    AutoVarContext,
    auto_var_names,
    build_render_env,
    compute_auto_vars,
)
from dotpromptz.typing import ParsedPrompt, PromptOutputConfig


def test_auto_var_names_exposes_registered_defaults() -> None:
    assert auto_var_names() == frozenset({'TIME', 'NAME', 'SCHEMA', 'INDEX', 'NUMBER', 'TEXT'})


def test_compute_auto_vars_includes_time_and_name(tmp_path: Path) -> None:
    prompt_file = tmp_path / 'hello.prompt'
    prompt_file.write_text('---\nversion: 1\n---\nHello', encoding='utf-8')
    ctx = AutoVarContext(
        prompt_file_path=prompt_file,
        now=datetime(2026, 1, 2, 3, 4, 5),
    )
    values = compute_auto_vars(ctx)
    assert values['NAME'] == 'hello'
    assert values['NUMBER'] == '1'
    assert values['TIME'] == '20260102_030405'


def test_compute_auto_vars_includes_schema_when_output_schema_present() -> None:
    prompt = ParsedPrompt(
        template='Schema: {{SCHEMA}}',
        output=PromptOutputConfig(
            format='json',
            schema_value={
                'type': 'object',
                'properties': {'name': {'type': 'string'}},
                'required': ['name'],
            },
            file_name='result',
        ),
    )
    ctx = AutoVarContext(
        prompt=prompt,
    )
    values = compute_auto_vars(ctx)
    assert 'SCHEMA' in values
    assert json.loads(values['SCHEMA']) == {
        'type': 'object',
        'properties': {'name': {'type': 'string'}},
        'required': ['name'],
    }


def test_compute_auto_vars_does_not_include_index_by_default() -> None:
    ctx = AutoVarContext(now=datetime(2026, 1, 2, 3, 4, 5))
    values = compute_auto_vars(ctx)
    assert 'INDEX' not in values


def test_build_render_env_does_not_leak_globals_across_calls() -> None:
    base_env = jinja2.Environment(autoescape=False, undefined=jinja2.Undefined)

    env1 = build_render_env(base_env, {'INDEX': '9'})
    text1 = env1.from_string('Index: {{INDEX}}').render({})
    assert text1 == 'Index: 9'

    env2 = build_render_env(base_env, None)
    text2 = env2.from_string('Index: {{INDEX}}').render({})
    assert text2 == 'Index: '


def test_compute_auto_vars_includes_text_for_chain_txt_input(tmp_path: Path) -> None:
    chain_file = tmp_path / 'chain.txt'
    chain_file.write_text('hello from chain', encoding='utf-8')

    ctx = AutoVarContext(
        chain_source=chain_file,
        chain_text='hello from chain',
    )

    values = compute_auto_vars(ctx)

    assert values['TEXT'] == 'hello from chain'
