"""Tests for infra_diagram.cli."""

from __future__ import annotations

import tempfile
from pathlib import Path

from click.testing import CliRunner

from infra_diagram.cli import cli

runner = CliRunner()

# ─── Sample data ─────────────────────────────────────────────────────

SAMPLE_TF = 'resource "aws_vpc" "main" {\n  cidr_block = "10.0.0.0/16"\n}\nresource "aws_subnet" "pub" {\n}\n'

SAMPLE_K8S = """apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
"""

SAMPLE_COMPOSE = """version: "3.8"
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
  db:
    image: postgres:15
"""


# ─── Version ─────────────────────────────────────────────────────────

class TestVersion:
    def test_version_flag(self):
        result = runner.invoke(cli, ["--version"])
        assert result.exit_code == 0
        assert "1.0.0" in result.output


# ─── Generate Command ────────────────────────────────────────────────

class TestGenerate:
    def test_terraform_auto_detect(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "main.tf").write_text(SAMPLE_TF, encoding="utf-8")
            result = runner.invoke(cli, ["generate", d])
            assert result.exit_code == 0
            assert "Infrastructure Components" in result.output or "graph" in result.output

    def test_explicit_type_terraform(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "main.tf").write_text(SAMPLE_TF, encoding="utf-8")
            result = runner.invoke(cli, ["generate", d, "--type", "terraform"])
            assert result.exit_code == 0

    def test_kubernetes_generate(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "app.yaml").write_text(SAMPLE_K8S, encoding="utf-8")
            result = runner.invoke(cli, ["generate", d, "--type", "kubernetes"])
            assert result.exit_code == 0

    def test_compose_generate(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "docker-compose.yml").write_text(SAMPLE_COMPOSE, encoding="utf-8")
            result = runner.invoke(cli, ["generate", d])
            assert result.exit_code == 0

    def test_html_export(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "main.tf").write_text(SAMPLE_TF, encoding="utf-8")
            html_path = str(Path(d) / "out.html")
            result = runner.invoke(cli, ["generate", d, "--html", html_path])
            assert result.exit_code == 0
            assert Path(html_path).exists()

    def test_json_export(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "main.tf").write_text(SAMPLE_TF, encoding="utf-8")
            json_path = str(Path(d) / "out.json")
            result = runner.invoke(cli, ["generate", d, "--json-output", json_path])
            assert result.exit_code == 0
            assert Path(json_path).exists()
            import json
            data = json.loads(Path(json_path).read_text(encoding="utf-8"))
            assert data["source_type"] == "terraform"
            assert data["node_count"] >= 2

    def test_mermaid_export(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "main.tf").write_text(SAMPLE_TF, encoding="utf-8")
            md_path = str(Path(d) / "diagram.md")
            result = runner.invoke(cli, ["generate", d, "--mermaid", md_path])
            assert result.exit_code == 0
            assert Path(md_path).exists()
            content = Path(md_path).read_text(encoding="utf-8")
            assert "```mermaid" in content

    def test_direction_option(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "main.tf").write_text(SAMPLE_TF, encoding="utf-8")
            result = runner.invoke(cli, ["generate", d, "--direction", "TB"])
            assert result.exit_code == 0

    def test_unknown_source_type(self):
        with tempfile.TemporaryDirectory() as d:
            # empty dir with no IaC files
            (Path(d) / "readme.txt").write_text("nothing", encoding="utf-8")
            result = runner.invoke(cli, ["generate", d])
            assert result.exit_code != 0

    def test_no_components_found(self):
        with tempfile.TemporaryDirectory() as d:
            (Path(d) / "empty.tf").write_text("# nothing\n", encoding="utf-8")
            result = runner.invoke(cli, ["generate", d])
            assert result.exit_code == 0
            assert "No infrastructure components" in result.output


# ─── Demo Command ────────────────────────────────────────────────────

class TestDemo:
    def test_demo_all(self):
        result = runner.invoke(cli, ["demo"])
        assert result.exit_code == 0
        assert "TERRAFORM" in result.output
        assert "KUBERNETES" in result.output
        assert "COMPOSE" in result.output

    def test_demo_terraform_only(self):
        result = runner.invoke(cli, ["demo", "--type", "terraform"])
        assert result.exit_code == 0
        assert "TERRAFORM" in result.output

    def test_demo_kubernetes_only(self):
        result = runner.invoke(cli, ["demo", "--type", "kubernetes"])
        assert result.exit_code == 0
        assert "KUBERNETES" in result.output

    def test_demo_compose_only(self):
        result = runner.invoke(cli, ["demo", "--type", "compose"])
        assert result.exit_code == 0
        assert "COMPOSE" in result.output

    def test_demo_with_html(self):
        with tempfile.TemporaryDirectory() as d:
            html_path = str(Path(d) / "demo.html")
            result = runner.invoke(cli, ["demo", "--type", "terraform", "--html", html_path])
            assert result.exit_code == 0
            assert Path(html_path).exists()

    def test_demo_direction(self):
        result = runner.invoke(cli, ["demo", "--type", "terraform", "--direction", "TB"])
        assert result.exit_code == 0

    def test_help(self):
        result = runner.invoke(cli, ["--help"])
        assert result.exit_code == 0
        assert "infra-diagram" in result.output

    def test_generate_help(self):
        result = runner.invoke(cli, ["generate", "--help"])
        assert result.exit_code == 0
        assert "PATH" in result.output

    def test_demo_help(self):
        result = runner.invoke(cli, ["demo", "--help"])
        assert result.exit_code == 0
