"""Tests for persisted workflow scheduler behavior."""

from __future__ import annotations

import tempfile
import unittest

from kiessclaw.runtime import build_agent_registry
from kiessclaw.scheduler import KiessScheduler
from kiessclaw.workflow.runner import WorkflowResult
from tests.test_helpers import base_config


class SchedulerTest(unittest.TestCase):
    """Validate schedule persistence and run-now execution."""

    def _scheduler(self, workspace_root: str) -> KiessScheduler:
        config = base_config()
        config["workspace"]["root"] = workspace_root
        registry = build_agent_registry(config)
        return KiessScheduler(config=config, registry=registry)

    def test_add_job_persists_to_scheduled_jobs_file(self) -> None:
        """Adding a job should create persisted schedule record."""
        with tempfile.TemporaryDirectory() as tempdir:
            scheduler = self._scheduler(tempdir)
            job_id = scheduler.add_job(
                usecase_id="outreach_sdr",
                cron="0 9 * * 1-5",
                inputs={
                    "company": "Acme",
                    "domain": "acme.com",
                    "contacts": [{"email": "cto@acme.com", "title": "CTO", "industry": "software", "employee_count": 50}],
                },
                dry_run=True,
            )
            jobs = scheduler.list_jobs()
            self.assertEqual(1, len(jobs))
            self.assertEqual(job_id, jobs[0]["job_id"])

    def test_list_jobs_returns_added_job(self) -> None:
        """Scheduler list should include newly added jobs."""
        with tempfile.TemporaryDirectory() as tempdir:
            scheduler = self._scheduler(tempdir)
            scheduler.add_job(
                usecase_id="outreach_sdr",
                cron="30 8 * * 1-5",
                inputs={
                    "company": "Acme",
                    "domain": "acme.com",
                    "contacts": [{"email": "ceo@acme.com", "title": "CEO", "industry": "software", "employee_count": 25}],
                },
                dry_run=True,
                job_id="job_alpha",
            )
            jobs = scheduler.list_jobs()
            self.assertEqual("job_alpha", jobs[0]["job_id"])

    def test_remove_job_deletes_from_file(self) -> None:
        """Removing a job should persist deletion."""
        with tempfile.TemporaryDirectory() as tempdir:
            scheduler = self._scheduler(tempdir)
            job_id = scheduler.add_job(
                usecase_id="outreach_sdr",
                cron="0 10 * * 1-5",
                inputs={
                    "company": "Acme",
                    "domain": "acme.com",
                    "contacts": [{"email": "cto@acme.com", "title": "CTO", "industry": "software", "employee_count": 50}],
                },
                dry_run=True,
            )
            self.assertTrue(scheduler.remove_job(job_id))
            self.assertEqual([], scheduler.list_jobs())

    def test_run_now_executes_workflow_and_returns_result(self) -> None:
        """run_now should execute the underlying workflow runner."""
        with tempfile.TemporaryDirectory() as tempdir:
            scheduler = self._scheduler(tempdir)
            job_id = scheduler.add_job(
                usecase_id="outreach_sdr",
                cron="0 9 * * 1-5",
                inputs={
                    "company": "Acme",
                    "domain": "acme.com",
                    "contacts": [{"email": "cto@acme.com", "title": "CTO", "industry": "software", "employee_count": 50}],
                },
                dry_run=True,
            )
            result = scheduler.run_now(job_id)
            self.assertIsInstance(result, WorkflowResult)
            jobs = scheduler.list_jobs()
            self.assertIsNotNone(jobs[0]["last_run"])

    def test_duplicate_job_id_raises_value_error(self) -> None:
        """Adding duplicate job IDs should fail loudly."""
        with tempfile.TemporaryDirectory() as tempdir:
            scheduler = self._scheduler(tempdir)
            scheduler.add_job(
                usecase_id="outreach_sdr",
                cron="0 9 * * 1-5",
                inputs={
                    "company": "Acme",
                    "domain": "acme.com",
                    "contacts": [{"email": "cto@acme.com", "title": "CTO", "industry": "software", "employee_count": 50}],
                },
                dry_run=True,
                job_id="job_dup",
            )
            with self.assertRaises(ValueError):
                scheduler.add_job(
                    usecase_id="outreach_sdr",
                    cron="15 9 * * 1-5",
                    inputs={
                        "company": "Acme",
                        "domain": "acme.com",
                        "contacts": [
                            {"email": "vp@acme.com", "title": "VP", "industry": "software", "employee_count": 40}
                        ],
                    },
                    dry_run=True,
                    job_id="job_dup",
                )


if __name__ == "__main__":
    unittest.main()
