"""Tests for job definition Pydantic models."""

import pytest
from pydantic import ValidationError

from fliiq.runtime.scheduler.models import (
    DeliveryConfig,
    JobDefinition,
    JobState,
    RunLogEntry,
    TriggerConfig,
)


def _cron_trigger(**kw):
    return TriggerConfig(type="cron", schedule="0 9 * * *", **kw)


def _webhook_trigger(**kw):
    return TriggerConfig(type="webhook", source="jira", **kw)


# --- TriggerConfig ---


def test_valid_cron_job():
    job = JobDefinition(
        name="daily-summary",
        trigger=_cron_trigger(),
        prompt="Summarize emails",
        skills=["gmail"],
        delivery=DeliveryConfig(type="email", to="me@example.com"),
    )
    assert job.name == "daily-summary"
    assert job.trigger.type == "cron"
    assert job.trigger.schedule == "0 9 * * *"
    assert job.skills == ["gmail"]
    assert job.delivery.type == "email"
    assert job.enabled is True
    assert job.state.run_count == 0


def test_valid_webhook_job():
    job = JobDefinition(
        name="jira-qa",
        trigger=_webhook_trigger(match={"event": "issue_updated"}),
        prompt="Run QA checklist",
    )
    assert job.trigger.type == "webhook"
    assert job.trigger.source == "jira"
    assert job.trigger.match == {"event": "issue_updated"}


def test_valid_at_job():
    job = JobDefinition(
        name="one-shot",
        trigger=TriggerConfig(type="at", schedule="2026-03-01T09:00:00Z"),
        prompt="Run once",
    )
    assert job.trigger.type == "at"
    assert job.trigger.schedule == "2026-03-01T09:00:00Z"


def test_valid_every_job():
    job = JobDefinition(
        name="heartbeat",
        trigger=TriggerConfig(type="every", schedule="30m"),
        prompt="Check status",
    )
    assert job.trigger.type == "every"
    assert job.trigger.schedule == "30m"


def test_reject_cron_without_schedule():
    with pytest.raises(ValidationError, match="requires 'schedule'"):
        TriggerConfig(type="cron")


def test_reject_webhook_without_source():
    with pytest.raises(ValidationError, match="requires 'source'"):
        TriggerConfig(type="webhook")


def test_reject_invalid_name_uppercase():
    with pytest.raises(ValidationError, match="lowercase alphanumeric"):
        JobDefinition(name="MyJob", trigger=_cron_trigger(), prompt="test")


def test_reject_invalid_name_spaces():
    with pytest.raises(ValidationError, match="lowercase alphanumeric"):
        JobDefinition(name="my job", trigger=_cron_trigger(), prompt="test")


def test_reject_invalid_name_too_short():
    with pytest.raises(ValidationError, match="at least 2 characters"):
        JobDefinition(name="x", trigger=_cron_trigger(), prompt="test")


def test_state_defaults():
    job = JobDefinition(
        name="test-job",
        trigger=_cron_trigger(),
        prompt="test",
    )
    assert job.state.last_run_at is None
    assert job.state.last_status is None
    assert job.state.next_run_at is None
    assert job.state.run_count == 0


def test_run_log_entry_defaults():
    from datetime import datetime, timezone

    entry = RunLogEntry(
        job_name="test-job",
        started_at=datetime.now(timezone.utc),
    )
    assert entry.status == "running"
    assert entry.iterations == 0
    assert entry.error is None
