#!/usr/bin/env python3
"""Version bumping script for cimonitor."""

import argparse
import re
import subprocess
import sys
from pathlib import Path


def get_project_dir() -> Path:
    """Get the project directory (parent of scripts/)."""
    return Path(__file__).parent.parent


def get_current_version() -> str:
    """Extract current version from pyproject.toml."""
    pyproject_path = get_project_dir() / "pyproject.toml"
    content = pyproject_path.read_text()

    match = re.search(r'^version = "([^"]+)"', content, re.MULTILINE)
    if not match:
        raise ValueError("Could not find version in pyproject.toml")

    return match.group(1)


def parse_version(version: str) -> tuple[int, int, int]:
    """Parse version string into major, minor, patch components."""
    parts = version.split(".")
    if len(parts) != 3:
        raise ValueError(f"Invalid version format: {version}")

    try:
        return int(parts[0]), int(parts[1]), int(parts[2])
    except ValueError as err:
        raise ValueError(f"Invalid version format: {version}") from err


def bump_version(version: str, bump_type: str) -> str:
    """Bump version based on type."""
    major, minor, patch = parse_version(version)

    if bump_type == "major":
        major += 1
        minor = 0
        patch = 0
    elif bump_type == "minor":
        minor += 1
        patch = 0
    elif bump_type == "patch":
        patch += 1
    else:
        raise ValueError(f"Invalid bump type: {bump_type}")

    return f"{major}.{minor}.{patch}"


def update_file(file_path: Path, pattern: str, replacement: str) -> None:
    """Update a file with regex pattern replacement."""
    content = file_path.read_text()
    new_content = re.sub(pattern, replacement, content, flags=re.MULTILINE)

    if content == new_content:
        raise ValueError(f"Pattern not found in {file_path}")

    file_path.write_text(new_content)


def update_version_files(new_version: str) -> None:
    """Update all files that contain version information."""
    project_dir = get_project_dir()

    # Update pyproject.toml
    update_file(
        project_dir / "pyproject.toml",
        r'^version = "[^"]+"',
        f'version = "{new_version}"',
    )

    # Update cimonitor/__init__.py
    update_file(
        project_dir / "cimonitor" / "__init__.py",
        r'^__version__ = "[^"]+"',
        f'__version__ = "{new_version}"',
    )


def sync_dependencies() -> None:
    """Update uv.lock by syncing dependencies."""
    project_dir = get_project_dir()
    result = subprocess.run(
        ["uv", "sync", "--extra", "dev"],
        cwd=project_dir,
        capture_output=True,
        text=True,
    )

    if result.returncode != 0:
        print(f"Warning: uv sync failed: {result.stderr}", file=sys.stderr)


def create_commit_and_tag(new_version: str) -> None:
    """Create a git commit and tag with the version."""
    project_dir = get_project_dir()

    # Add all changes
    result = subprocess.run(
        ["git", "add", "-A"],
        cwd=project_dir,
        capture_output=True,
        text=True,
    )

    if result.returncode != 0:
        print(f"Warning: git add failed: {result.stderr}", file=sys.stderr)
        return

    # Create commit
    commit_message = f"v{new_version}"
    result = subprocess.run(
        ["git", "commit", "-m", commit_message],
        cwd=project_dir,
        capture_output=True,
        text=True,
    )

    if result.returncode != 0:
        print(f"Warning: git commit failed: {result.stderr}", file=sys.stderr)
        return

    print(f"✅ Created commit: {commit_message}")

    # Create tag
    tag_name = f"v{new_version}"
    result = subprocess.run(
        ["git", "tag", tag_name],
        cwd=project_dir,
        capture_output=True,
        text=True,
    )

    if result.returncode != 0:
        print(f"Warning: git tag failed: {result.stderr}", file=sys.stderr)
        return

    print(f"✅ Created tag: {tag_name}")
    print(f"💡 Run 'git push origin {tag_name}' to trigger PyPI release")


def main() -> None:
    """Main function."""
    parser = argparse.ArgumentParser(description="Bump version for cimonitor")
    group = parser.add_mutually_exclusive_group()
    group.add_argument("--major", action="store_const", const="major", dest="bump_type")
    group.add_argument("--minor", action="store_const", const="minor", dest="bump_type")
    group.add_argument("--patch", action="store_const", const="patch", dest="bump_type")
    parser.set_defaults(bump_type="patch")

    args = parser.parse_args()

    try:
        current_version = get_current_version()
        print(f"Current version: {current_version}")

        new_version = bump_version(current_version, args.bump_type)
        print(f"New version: {new_version}")

        update_version_files(new_version)
        sync_dependencies()
        create_commit_and_tag(new_version)

        print("✅ Version bumped successfully")
        print("📝 Files updated:")
        print("   - pyproject.toml")
        print("   - cimonitor/__init__.py")
        print("   - uv.lock")

    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()