"""
Extension manifest 버전 bump 강제 정책 (task-2447).

Usage:
  python3 scripts/extension_version_bump.py --check
  python3 scripts/extension_version_bump.py --sync
  python3 scripts/extension_version_bump.py --check --extension-dir /custom/path
"""

import argparse
import json
import os
import re
import sys
from pathlib import Path

DEFAULT_EXTENSION_DIR = "/home/jay/projects/InsuRo/extension"
DEFAULT_CONFIG_FILE = "/home/jay/projects/InsuRo/server/config/extension_version.json"
DEFAULT_POPUP_FILE = "/home/jay/projects/InsuRo/extension/popup.html"
DEFAULT_GITHUB_REPO = "JonghyukJeon/InsuRo"

SEMVER_RE = re.compile(r"^\d+\.\d+\.\d+$")
HARDCODED_VERSION_RE = re.compile(r"v\d+\.\d+\.\d+")
GITHUB_RELEASE_URL_RE = re.compile(
    r"^https://github\.com/.+/releases/download/extension-v\d+\.\d+\.\d+/insuro-helper-\d+\.\d+\.\d+\.zip$"
)
LEGACY_URL_RE = re.compile(r"/downloads/")


def load_manifest(extension_dir: Path):
    manifest_path = extension_dir / "manifest.json"
    if not manifest_path.exists():
        print(f"FAIL: manifest.json 없음 — {manifest_path}")
        sys.exit(1)
    with open(manifest_path, encoding="utf-8") as f:
        data = json.load(f)
    version = data.get("version", "")
    if not SEMVER_RE.match(version):
        print(f"FAIL: manifest.json의 version 키가 없거나 semver 형식(X.Y.Z) 불일치 — '{version}'")
        sys.exit(1)
    return version


def check_mode(extension_dir: Path, config_file: Path, popup_file: Path) -> int:
    failures = []

    # 1. manifest.json 존재 + version 키 존재 (semver 형식 X.Y.Z)
    manifest_path = extension_dir / "manifest.json"
    if not manifest_path.exists():
        failures.append(f"manifest.json 없음 — {manifest_path}")
        manifest_version = None
    else:
        try:
            with open(manifest_path, encoding="utf-8") as f:
                manifest_data = json.load(f)
            manifest_version = manifest_data.get("version", "")
            if not SEMVER_RE.match(manifest_version):
                failures.append(f"manifest.json version 키 없음 또는 semver 불일치 — '{manifest_version}'")
                manifest_version = None
        except Exception as e:
            failures.append(f"manifest.json 파싱 오류 — {e}")
            manifest_version = None

    # 2. popup.html hardcoded version 체크
    if popup_file.exists():
        popup_content = popup_file.read_text(encoding="utf-8")
        if HARDCODED_VERSION_RE.search(popup_content):
            failures.append(
                "popup.html에 hardcoded version 발견 — chrome.runtime.getManifest() 사용 필요"
            )
    else:
        failures.append(f"popup.html 없음 — {popup_file}")

    # 3. extension_version.json version/latest_version 키가 manifest version과 일치
    if config_file.exists() and manifest_version:
        try:
            with open(config_file, encoding="utf-8") as f:
                config_data = json.load(f)
            config_version = config_data.get("version") or config_data.get("latest_version", "")
            if config_version != manifest_version:
                failures.append(
                    f"extension_version.json version({config_version!r}) ≠ manifest version({manifest_version!r})"
                )
        except Exception as e:
            failures.append(f"extension_version.json 파싱 오류 — {e}")
    elif not config_file.exists():
        failures.append(f"extension_version.json 없음 — {config_file}")

    # 4. download_url GitHub release URL 패턴 체크
    if config_file.exists():
        try:
            with open(config_file, encoding="utf-8") as f:
                config_data = json.load(f)
            download_url = config_data.get("download_url", "")
            if LEGACY_URL_RE.search(download_url):
                failures.append(
                    f"download_url에 legacy '/downloads/...' 경로 발견 — GitHub release URL 필요 ({download_url!r})"
                )
            elif download_url and not GITHUB_RELEASE_URL_RE.match(download_url):
                failures.append(
                    f"download_url이 GitHub release URL 패턴 불일치 — ({download_url!r})"
                )
        except Exception:
            pass  # 이미 위에서 파싱 오류 처리됨

    if failures:
        print("FAIL:")
        for f in failures:
            print(f"  - {f}")
        return 1
    else:
        print(f"PASS: manifest version={manifest_version!r}, extension_version.json 일치, popup.html 정상")
        return 0


def sync_mode(extension_dir: Path, config_file: Path) -> int:
    version = load_manifest(extension_dir)

    github_repo = os.environ.get("INSURO_GITHUB_REPO", DEFAULT_GITHUB_REPO)

    config_data = {
        "latest_version": version,
        "version": version,
        "download_url": (
            f"https://github.com/{github_repo}/releases/download/"
            f"extension-v{version}/insuro-helper-{version}.zip"
        ),
        "release_notes": f"Extension v{version}",
        "release_notes_url": (
            f"https://github.com/{github_repo}/releases/tag/extension-v{version}"
        ),
    }

    config_file.parent.mkdir(parents=True, exist_ok=True)
    with open(config_file, "w", encoding="utf-8") as f:
        json.dump(config_data, f, indent=2, ensure_ascii=False)
        f.write("\n")

    print(f"PASS: extension_version.json 갱신 완료 — version={version!r}, repo={github_repo!r}")
    print(f"  파일: {config_file}")
    return 0


def main():
    parser = argparse.ArgumentParser(
        description="Extension manifest 버전 bump 강제 정책 (task-2447)"
    )
    mode_group = parser.add_mutually_exclusive_group(required=True)
    mode_group.add_argument(
        "--check",
        action="store_true",
        help="검증 모드: 불일치 시 exit 1",
    )
    mode_group.add_argument(
        "--sync",
        action="store_true",
        help="동기화 모드: extension_version.json을 manifest 기준으로 갱신",
    )
    parser.add_argument(
        "--extension-dir",
        default=DEFAULT_EXTENSION_DIR,
        help=f"extension 디렉토리 경로 (기본: {DEFAULT_EXTENSION_DIR})",
    )
    parser.add_argument(
        "--config-file",
        default=DEFAULT_CONFIG_FILE,
        help=f"extension_version.json 경로 (기본: {DEFAULT_CONFIG_FILE})",
    )
    parser.add_argument(
        "--popup-file",
        default=DEFAULT_POPUP_FILE,
        help=f"popup.html 경로 (기본: {DEFAULT_POPUP_FILE})",
    )

    args = parser.parse_args()

    extension_dir = Path(args.extension_dir)
    config_file = Path(args.config_file)
    popup_file = Path(args.popup_file)

    if args.check:
        sys.exit(check_mode(extension_dir, config_file, popup_file))
    elif args.sync:
        sys.exit(sync_mode(extension_dir, config_file))


if __name__ == "__main__":
    main()
