"""
test_extension_version_bump.py — task-2447 CI guard 회귀 테스트
"""
import subprocess
import json
from pathlib import Path
import sys

SCRIPT = Path(__file__).resolve().parent.parent.parent / "scripts" / "extension_version_bump.py"


def _run(extension_dir: Path, config_file: Path, popup_file: Path, mode: str):
    """스크립트를 subprocess로 실행하고 결과를 반환."""
    result = subprocess.run(
        [
            sys.executable,
            str(SCRIPT),
            mode,
            "--extension-dir", str(extension_dir),
            "--config-file", str(config_file),
            "--popup-file", str(popup_file),
        ],
        capture_output=True,
        text=True,
    )
    return result


def _make_manifest(extension_dir: Path, version: str):
    """임시 extension 디렉토리에 manifest.json 생성."""
    extension_dir.mkdir(parents=True, exist_ok=True)
    manifest = {
        "manifest_version": 3,
        "name": "InsuRo Helper",
        "version": version,
    }
    (extension_dir / "manifest.json").write_text(
        json.dumps(manifest, indent=2), encoding="utf-8"
    )


def _make_popup(popup_file: Path, has_hardcoded_version: bool):
    """popup.html 생성. has_hardcoded_version=True 이면 'v0.1.0' 포함."""
    popup_file.parent.mkdir(parents=True, exist_ok=True)
    if has_hardcoded_version:
        content = '<div class="footer">v0.1.0 · 인카 FA 전용</div>'
    else:
        content = '<div class="footer">인카 FA 전용</div>'
    popup_file.write_text(content, encoding="utf-8")


def _make_config(config_file: Path, version: str, download_url: str | None = None):
    """extension_version.json 생성."""
    config_file.parent.mkdir(parents=True, exist_ok=True)
    if download_url is None:
        download_url = (
            f"https://github.com/JonghyukJeon/InsuRo/releases/download/"
            f"extension-v{version}/insuro-helper-{version}.zip"
        )
    config = {
        "latest_version": version,
        "version": version,
        "download_url": download_url,
        "release_notes": f"Extension v{version}",
        "release_notes_url": f"https://github.com/JonghyukJeon/InsuRo/releases/tag/extension-v{version}",
    }
    config_file.write_text(json.dumps(config, indent=2), encoding="utf-8")


# ────────────────────────────── 테스트 케이스 ──────────────────────────────

def test_check_passes_when_aligned(tmp_path):
    """manifest(0.4.1) + popup(no version) + config(version=0.4.1 + GitHub URL) → exit 0"""
    ext_dir = tmp_path / "extension"
    config_file = tmp_path / "config" / "extension_version.json"
    popup_file = ext_dir / "popup.html"

    _make_manifest(ext_dir, "0.4.1")
    _make_popup(popup_file, has_hardcoded_version=False)
    _make_config(config_file, "0.4.1")

    result = _run(ext_dir, config_file, popup_file, "--check")
    assert result.returncode == 0, f"Expected exit 0, got {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr}"
    assert "PASS" in result.stdout


def test_check_fails_when_popup_has_hardcoded_version(tmp_path):
    """popup.html에 'v0.1.0' 포함 → exit 1"""
    ext_dir = tmp_path / "extension"
    config_file = tmp_path / "config" / "extension_version.json"
    popup_file = ext_dir / "popup.html"

    _make_manifest(ext_dir, "0.4.1")
    _make_popup(popup_file, has_hardcoded_version=True)
    _make_config(config_file, "0.4.1")

    result = _run(ext_dir, config_file, popup_file, "--check")
    assert result.returncode == 1, f"Expected exit 1, got {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr}"
    assert "FAIL" in result.stdout
    assert "hardcoded version" in result.stdout


def test_check_fails_when_manifest_config_mismatch(tmp_path):
    """manifest '0.4.1', config '0.1.0' → exit 1"""
    ext_dir = tmp_path / "extension"
    config_file = tmp_path / "config" / "extension_version.json"
    popup_file = ext_dir / "popup.html"

    _make_manifest(ext_dir, "0.4.1")
    _make_popup(popup_file, has_hardcoded_version=False)
    _make_config(config_file, "0.1.0")

    result = _run(ext_dir, config_file, popup_file, "--check")
    assert result.returncode == 1, f"Expected exit 1, got {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr}"
    assert "FAIL" in result.stdout


def test_check_fails_when_download_url_legacy(tmp_path):
    """config download_url='/downloads/insuro-helper-0.4.1.zip' → exit 1"""
    ext_dir = tmp_path / "extension"
    config_file = tmp_path / "config" / "extension_version.json"
    popup_file = ext_dir / "popup.html"

    _make_manifest(ext_dir, "0.4.1")
    _make_popup(popup_file, has_hardcoded_version=False)
    _make_config(config_file, "0.4.1", download_url="/downloads/insuro-helper-0.4.1.zip")

    result = _run(ext_dir, config_file, popup_file, "--check")
    assert result.returncode == 1, f"Expected exit 1, got {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr}"
    assert "FAIL" in result.stdout
    assert "legacy" in result.stdout


def test_sync_writes_correct_schema(tmp_path):
    """--sync 실행 후 config 파일에 GitHub URL + 정확한 schema 작성 확인"""
    ext_dir = tmp_path / "extension"
    config_file = tmp_path / "config" / "extension_version.json"
    popup_file = ext_dir / "popup.html"

    _make_manifest(ext_dir, "0.4.1")
    _make_popup(popup_file, has_hardcoded_version=False)
    # config 파일은 사전에 없어도 됨 (sync가 생성)

    result = _run(ext_dir, config_file, popup_file, "--sync")
    assert result.returncode == 0, f"Expected exit 0, got {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr}"
    assert "PASS" in result.stdout

    # 파일 내용 검증
    assert config_file.exists(), "config 파일이 생성되어야 함"
    with open(config_file, encoding="utf-8") as f:
        data = json.load(f)

    assert data["latest_version"] == "0.4.1"
    assert data["version"] == "0.4.1"
    assert "github.com" in data["download_url"]
    assert "extension-v0.4.1" in data["download_url"]
    assert "insuro-helper-0.4.1.zip" in data["download_url"]
    assert data["release_notes"] == "Extension v0.4.1"
    assert "releases/tag/extension-v0.4.1" in data["release_notes_url"]


def test_check_fails_when_manifest_missing(tmp_path):
    """extension dir에 manifest 없음 → exit 1"""
    ext_dir = tmp_path / "extension"
    ext_dir.mkdir(parents=True, exist_ok=True)
    config_file = tmp_path / "config" / "extension_version.json"
    popup_file = ext_dir / "popup.html"

    # manifest 없이 popup과 config만 생성
    _make_popup(popup_file, has_hardcoded_version=False)
    _make_config(config_file, "0.4.1")

    result = _run(ext_dir, config_file, popup_file, "--check")
    assert result.returncode == 1, f"Expected exit 1, got {result.returncode}\nstdout: {result.stdout}\nstderr: {result.stderr}"
    assert "FAIL" in result.stdout
