"""Tests for the AI deploy script (scripts/ai_deploy.py)."""

from __future__ import annotations

import json
import os
import sys
from unittest.mock import patch

import pytest

# Add scripts dir to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts"))


def test_phase_result_to_dict():
    """PhaseResult.to_dict should serialize correctly."""
    from ai_deploy import PhaseResult

    result = PhaseResult(name="build", success=True, duration_s=1.5, output="ok")
    d = result.to_dict()
    assert d["phase"] == "build"
    assert d["success"] is True
    assert d["duration_s"] == 1.5
    assert d["output"] == "ok"


def test_deploy_report_to_dict():
    """DeployReport.to_dict should include phases and rollback info."""
    from ai_deploy import DeployReport, PhaseResult

    report = DeployReport(
        started_at="2026-01-01T00:00:00Z",
        finished_at="2026-01-01T00:05:00Z",
        overall_success=True,
    )
    report.phases.append(PhaseResult(name="build", success=True))
    d = report.to_dict()
    assert d["overall_success"] is True
    assert len(d["phases"]) == 1
    assert d["rollback_performed"] is False


def test_phase_build_skip():
    """phase_build should skip when --skip-build is set."""
    from ai_deploy import phase_build

    result = phase_build(skip_build=True, dry_run=False)
    assert result.success is True
    assert "skipped" in result.output.lower()


def test_phase_build_dry_run():
    """phase_build should return dry-run message in dry-run mode."""
    from ai_deploy import phase_build

    result = phase_build(skip_build=False, dry_run=True)
    assert result.success is True
    assert "DRY-RUN" in result.output


def test_phase_tests_skip():
    """phase_tests should skip when --skip-tests is set."""
    from ai_deploy import phase_tests

    result = phase_tests(skip_tests=True, dry_run=False)
    assert result.success is True
    assert "skipped" in result.output.lower()


def test_phase_tests_dry_run():
    """phase_tests should return dry-run message in dry-run mode."""
    from ai_deploy import phase_tests

    result = phase_tests(skip_tests=False, dry_run=True)
    assert result.success is True
    assert "DRY-RUN" in result.output


def test_phase_deploy_missing_env():
    """phase_deploy should fail when env vars are missing."""
    from ai_deploy import phase_deploy

    # Ensure env vars are not set
    with patch.dict(os.environ, {}, clear=True):
        result = phase_deploy(dry_run=False)
    assert result.success is False
    assert "COOLIFY" in result.error


def test_phase_deploy_dry_run_with_env():
    """phase_deploy should succeed in dry-run mode with env vars set."""
    from ai_deploy import phase_deploy

    with patch.dict(os.environ, {"COOLIFY_API_TOKEN": "test", "COOLIFY_APP_UUID": "uuid-123"}):
        result = phase_deploy(dry_run=True)
    assert result.success is True
    assert "DRY-RUN" in result.output
    assert "uuid-123" in result.output


def test_phase_rollback_missing_env():
    """phase_rollback should fail when env vars are missing."""
    from ai_deploy import phase_rollback

    with patch.dict(os.environ, {}, clear=True):
        result = phase_rollback(dry_run=False)
    assert result.success is False
    assert "COOLIFY" in result.error


def test_run_pipeline_dry_run_all_skip():
    """Full pipeline in dry-run with all skips should succeed with env vars."""
    from ai_deploy import run_pipeline

    with patch.dict(os.environ, {"COOLIFY_API_TOKEN": "test", "COOLIFY_APP_UUID": "uuid-123"}):
        report = run_pipeline(skip_build=True, skip_tests=True, dry_run=True)
    assert report.overall_success is True
    assert len(report.phases) == 3  # build, tests, deploy
    assert all(p.success for p in report.phases)
    assert report.rollback_performed is False


def test_run_pipeline_deploy_fail_triggers_rollback():
    """Pipeline should trigger rollback when deploy fails."""
    from ai_deploy import run_pipeline

    with patch.dict(os.environ, {}, clear=True):
        report = run_pipeline(skip_build=True, skip_tests=True, dry_run=False)
    assert report.overall_success is False
    assert report.rollback_performed is True
    assert len(report.phases) == 4  # build, tests, deploy, rollback
