"""Unit tests for the ``ziran pentest`` CLI command."""

from __future__ import annotations

import pytest
from click.testing import CliRunner

from ziran.domain.entities.pentest import (
    PentestPlan,
    PentestSession,
    PentestStatus,
    PentestStep,
    PentestStepType,
)
from ziran.interfaces.cli.main import cli


@pytest.fixture()
def runner() -> CliRunner:
    return CliRunner()


def _completed_session() -> PentestSession:
    session = PentestSession(
        status=PentestStatus.COMPLETE,
        max_iterations=10,
    )
    session.plan = PentestPlan(goal="Test goal")
    session.total_vulnerabilities = 1
    session.total_attacks_executed = 5
    session.iteration_count = 3
    session.add_step(
        PentestStep(
            step_type=PentestStepType.SCAN,
            reasoning="Initial scan",
            result_summary="Scan complete: 1 vulns found",
            duration_seconds=2.5,
        )
    )
    return session


# ──────────────────────────────────────────────────────────────────────
# Basic CLI option validation
# ──────────────────────────────────────────────────────────────────────


@pytest.mark.unit
class TestPentestCLIOptions:
    """Tests for CLI option validation."""

    def test_missing_goal_fails(self, runner: CliRunner) -> None:
        result = runner.invoke(
            cli, ["pentest", "--llm-provider", "openai", "--llm-model", "gpt-4o"]
        )
        assert result.exit_code != 0
        assert "goal" in result.output.lower() or "required" in result.output.lower()

    def test_missing_llm_provider_fails(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["pentest", "--goal", "test", "--llm-model", "gpt-4o"])
        assert result.exit_code != 0

    def test_missing_llm_model_fails(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["pentest", "--goal", "test", "--llm-provider", "openai"])
        assert result.exit_code != 0

    def test_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["pentest", "--help"])
        assert result.exit_code == 0
        assert "pentesting agent" in result.output.lower()
        assert "--goal" in result.output
        assert "--interactive" in result.output
        assert "--llm-provider" in result.output
        assert "--llm-model" in result.output

    def test_no_target_or_framework_exits(self, runner: CliRunner) -> None:
        """Without --target or --framework, should exit with error."""
        result = runner.invoke(
            cli,
            [
                "pentest",
                "--goal",
                "test",
                "--llm-provider",
                "openai",
                "--llm-model",
                "gpt-4o",
            ],
        )
        # Should exit with an error about --target or --framework
        assert result.exit_code != 0


# ──────────────────────────────────────────────────────────────────────
# Autonomous mode
# ──────────────────────────────────────────────────────────────────────


@pytest.mark.unit
class TestPentestAutonomousMode:
    """Tests for the autonomous pentesting mode through CLI."""

    pass  # Full integration of CLI → orchestrator requires complex mocking
    # The orchestrator itself is tested in test_pentest_orchestrator.py
