#!/usr/bin/env python3
"""
Stage 1 Bootstrap - No dependencies required
Run this before poetry install to initialize your project
"""

import os
import subprocess
import sys
from pathlib import Path

# Get the project root directory (parent of scripts directory)
SCRIPT_DIR = Path(__file__).parent.resolve()
PROJECT_ROOT = SCRIPT_DIR.parent


def run_command(cmd):
    """Run command and return output"""
    try:
        result = subprocess.run(cmd, check=False, shell=True, capture_output=True, text=True)
        if result.returncode != 0:
            print(f"Error: {result.stderr}")
            return None
        return result.stdout.strip()
    except Exception as e:
        print(f"Error running command: {e}")
        return None


def parse_git_remote():
    """Extract GitHub account and repo from git remote"""
    remote = run_command("git remote get-url origin")
    if not remote or "github.com" not in remote:
        return None, None

    # Handle both SSH and HTTPS URLs
    if remote.startswith("git@"):
        # SSH format: git@github.com:account/repo.git
        path_part = remote.split(":")[-1]
    else:
        # HTTPS format: https://github.com/account/repo.git
        path_part = remote.split("github.com/")[-1]

    # Clean up .git suffix (use endswith to avoid rstrip issues)
    if path_part.endswith(".git"):
        path_part = path_part[:-4]  # Remove last 4 characters (.git)

    # Split into account/repo
    parts = path_part.strip("/").split("/")

    if len(parts) >= 2:
        account = parts[0].strip()
        repo = parts[1].strip()

        # Validate repository name
        if len(repo) < 3:
            print(f"⚠️  Repository name '{repo}' seems too short. Full remote: {remote}")
            print("Please verify this is correct or provide the name manually.")

        return account, repo

    print(f"❌ Could not parse git remote properly. Parts: {parts}")
    return None, None


def generate_claude_md(repo, module_name):
    """Generate optimized CLAUDE.md for the new project"""
    content = f"""# CLAUDE.md

This file provides guidance to Claude Code when working with the {repo} project.

## Project Overview

**{repo}** - Python library with Poetry, automated CI/CD, security scanning, and optional AWS integration.

## Development Commands

### Core Development
- `poetry install` - Install dependencies
- `poetry run pytest` - Run tests (fast subset)
- `poetry run pytest -m slow` - Run AWS integration tests
- `poetry run ruff check --fix` - Lint and fix code
- `poetry run black .` - Format code
- `poetry run pre-commit run --all-files` - Run all hooks

### Security & Compliance
- `poetry install --with security` - Install security tools
- `poetry run bandit -r src/` - Security analysis
- `poetry run safety check` - Vulnerability check
- `poetry run pip-audit` - Package audit

## Coding Preferences

### Code Style
- **Black formatting** (88 char line length)
- **Ruff linting** with comprehensive rules
- **Google-style docstrings** for public APIs
- **Type hints** for function signatures

### Architecture
- **Library-first design** - Core logic in library modules, CLI as thin wrapper
- **Test-driven development** - Write tests before implementation
- **Explicit error handling** - Custom exceptions, never bare except
- **Environment-based configuration** - Use .env files, sensible defaults

### Testing
- Use `@pytest.mark.slow` for AWS operations
- Mock external dependencies, test business logic
- Use `pytest-click` for CLI testing
- Focus on meaningful tests over coverage percentage

## Project Structure

```
src/{module_name}/
├── __init__.py          # Public API exports
├── core/                # Core business logic
├── cli.py               # Click CLI interface
└── config.py            # Configuration management

tests/
├── test_*.py            # Test files
└── conftest.py          # Test fixtures
```

## Key Patterns

### Error Handling
```python
class {module_name.replace("_", " ").title().replace(" ", "")}Error(Exception):
    \"\"\"Base exception for {repo}.\"\"\"
    pass
```

### Configuration
```python
import os
from pathlib import Path

class Config:
    def __init__(self):
        self.debug = os.getenv("DEBUG", "false").lower() == "true"
        self.timeout = int(os.getenv("TIMEOUT", "30"))
```

### CLI Design
```python
import click

@click.command()
@click.option('--debug', is_flag=True, help='Enable debug mode')
def main(debug):
    \"\"\"Main CLI entry point.\"\"\"
    pass
```

## Environment Variables

- `DEBUG` - Enable debug logging (default: false)
- `GH_TOKEN` - GitHub token for CI/CD
- `PYTHON_VERSION` - Python version for CI (default: 3.12)

AWS-specific (if enabled):
- `TESTING_PIPELINE_EXECUTION_ROLE` - IAM role for testing
- `TESTING_ARTIFACTS_BUCKET` - S3 bucket for artifacts

## Issue-Driven Development Workflow

### Planning with GitHub Issues
- Use GitHub Issues as Claude's task management system
- Claude can create, read, and update issues for planning
- Link issues to feature branches using conventional naming
- Track progress through issue status and labels

### Implementation Pattern
1. **Create Issue**: Claude creates detailed GitHub issue with requirements
2. **Create Branch**: `feat/issue-{{number}}-{{description}}` naming convention
3. **Implement**: Claude develops solution with proper testing
4. **Submit PR**: Link PR to issue with "closes #123" in body
5. **Pipeline**: Automated CI/CD validates and deploys
6. **Release**: Merge to main triggers semantic release

### Claude Integration Commands
```bash
# List current issues
gh issue list

# Create new issue
gh issue create --title "feat: add X" --label enhancement

# Comment on issue
gh issue comment {{number}} --body "Progress update"

# Create branch for issue
git checkout -b feat/issue-{{number}}-{{description}}

# Create PR that closes issue
gh pr create --title "feat: add X" --body "closes #{{number}}"
```

### Secrets Management Integration
- `.env` file with local secrets (gitignored)
- `chezmoi` + age encryption for remote backup
- `ai-gh-push` command to sync secrets to GitHub
- GitHub Actions seamless secret injection
- Zero logging of sensitive data

## Development Workflow

- **Conventional commits** trigger semantic releases
- **GitHub Actions** handles CI/CD, security scanning, publishing
- **Pre-commit hooks** enforce code quality
- **Branch protection** on main branch

## Quick Reference

### Adding Features
1. Write failing tests first
2. Implement minimum viable solution
3. Refactor for clarity
4. Update documentation

### Debugging
- Use `breakpoint()` for interactive debugging
- Check `pytest.log` for test logs
- Use `--pdb` flag with pytest for post-mortem debugging

### Common Issues
- Use `pathlib.Path` for cross-platform compatibility
- Mock external dependencies in tests
- Keep runtime dependencies minimal

This project uses enterprise-grade tooling while encouraging creative solutions within established patterns.
"""

    claude_md_path = PROJECT_ROOT / "CLAUDE.md"
    with open(claude_md_path, "w", encoding="utf-8") as f:
        f.write(content)
    print("✅ Generated optimized CLAUDE.md")


def create_env_file(account, repo):
    """Create initial .env file"""
    content = f"""# GitHub Configuration
GH_REPO={repo}
GH_ACCOUNT={account}
GH_TOKEN=# TODO: Add your GitHub personal access token here

# Python version for CI/CD
PYTHON_VERSION=3.12

# AWS Configuration
TESTING_REGION=us-east-1

# These will be populated by bootstrap-stage2.py after SAM pipeline bootstrap
TESTING_PIPELINE_EXECUTION_ROLE=# Run bootstrap-stage2.py after sam pipeline bootstrap
TESTING_CLOUDFORMATION_EXECUTION_ROLE=# Run bootstrap-stage2.py after sam pipeline bootstrap
TESTING_ARTIFACTS_BUCKET=# Run bootstrap-stage2.py after sam pipeline bootstrap
AWS_ACCOUNT_ID=# Run bootstrap-stage2.py after sam pipeline bootstrap

# Git merge strategy for PRs (options: squash, rebase, merge)
MERGE_STRATEGY=squash
"""

    env_path = PROJECT_ROOT / ".env"
    with open(env_path, "w", encoding="utf-8") as f:
        f.write(content)
    print("✅ Created .env file")


def replace_in_file(filepath, old_text, new_text):
    """Replace text in a file"""
    try:
        # Ensure filepath is absolute
        if not Path(filepath).is_absolute():
            filepath = PROJECT_ROOT / filepath

        with open(filepath, encoding="utf-8") as f:
            content = f.read()

        if old_text in content:
            content = content.replace(old_text, new_text)
            with open(filepath, "w", encoding="utf-8") as f:
                f.write(content)
            return True
    except Exception as e:
        print(f"Error updating {filepath}: {e}")
    return False


def clear_changelog():
    """Clear the changelog for new projects"""
    changelog_content = """# CHANGELOG

<!-- version list -->

## v0.0.0 (unreleased)

- Initial project setup

"""

    try:
        changelog_path = PROJECT_ROOT / "CHANGELOG.md"
        with open(changelog_path, "w", encoding="utf-8") as f:
            f.write(changelog_content)
        print("✅ Cleared CHANGELOG.md for new project")
        return True
    except Exception as e:
        print(f"⚠️  Error clearing CHANGELOG.md: {e}")
        return False


def replace_license():
    """Replace LICENSE file with a generic template"""
    license_content = """TODO: Add appropriate license for your project.

Popular open-source license options:
- MIT License: https://choosealicense.com/licenses/mit/
- Apache License 2.0: https://choosealicense.com/licenses/apache-2.0/
- GNU GPLv3: https://choosealicense.com/licenses/gpl-3.0/
- BSD 3-Clause: https://choosealicense.com/licenses/bsd-3-clause/

For help choosing a license, visit: https://choosealicense.com/

Remember to:
1. Replace this file with your chosen license text
2. Update the license field in pyproject.toml
3. Update any license badges in README.md
"""

    try:
        license_path = PROJECT_ROOT / "LICENSE"
        with open(license_path, "w", encoding="utf-8") as f:
            f.write(license_content)
        print("✅ Replaced LICENSE file with template")
        return True
    except Exception as e:
        print(f"⚠️  Error replacing LICENSE file: {e}")
        return False


def validate_replacements(old_name, old_module, exclude_files=None):
    """Check for remaining hardcoded references"""
    if exclude_files is None:
        exclude_files = {"CHANGELOG.md", ".git", "__pycache__", ".venv", "htmlcov", ".pytest_cache"}

    print("\n🔍 Validating template replacements...")

    issues_found = False
    search_terms = [old_name, old_module, "svange"]

    for term in search_terms:
        print(f"\nSearching for remaining '{term}' references...")

        # Use git grep if available (faster and respects .gitignore)
        try:
            result = subprocess.run(
                ["git", "grep", "-l", term],
                capture_output=True,
                text=True,
                cwd=PROJECT_ROOT,
                check=False,
            )

            if result.returncode == 0 and result.stdout:
                files = result.stdout.strip().split("\n")
                filtered_files = [
                    f for f in files if not any(exclude in f for exclude in exclude_files)
                ]

                if filtered_files:
                    issues_found = True
                    print(f"⚠️  Found '{term}' in {len(filtered_files)} file(s):")
                    for file in filtered_files[:10]:  # Show first 10
                        print(f"   - {file}")
                    if len(filtered_files) > 10:
                        print(f"   ... and {len(filtered_files) - 10} more files")
        except Exception:
            # Fallback to Python search if git grep not available
            pass

    if not issues_found:
        print("\n✅ No hardcoded references found!")
    else:
        print("\n⚠️  Some hardcoded references remain. These may need manual updates.")

    return not issues_found


def customize_template(
    old_name, new_name, old_module, new_module, old_account="svange", new_account=None
):
    """Replace template strings with project-specific values"""
    files_to_update = [
        "pyproject.toml",
        "README.md",
        ".github/workflows/pipeline.yaml",
        ".github/CODEOWNERS",
        ".github/FUNDING.yaml",
        ".github/ISSUE_TEMPLATE/bug_report.md",
        ".github/ISSUE_TEMPLATE/feature_request.md",
        "src/augint_library/__init__.py",
        "src/augint_library/cli.py",
        "src/augint_library/telemetry.py",
        "tests/test_example.py",
        "tests/test_10_stub.py",
    ]

    # Also handle directory rename
    old_src = PROJECT_ROOT / "src" / old_module
    new_src = PROJECT_ROOT / "src" / new_module

    if old_src.exists() and old_module != new_module:
        old_src.rename(new_src)
        print(f"✅ Renamed {old_src} to {new_src}")

        # Update file paths after rename
        files_to_update = [f.replace(old_module, new_module) for f in files_to_update]

    updated = 0
    for filepath in files_to_update:
        # Ensure absolute path
        abs_filepath = PROJECT_ROOT / filepath if not Path(filepath).is_absolute() else filepath
        if abs_filepath.exists():
            # Replace project name
            if replace_in_file(abs_filepath, old_name, new_name):
                updated += 1
            # Replace module name
            if replace_in_file(abs_filepath, old_module, new_module):
                updated += 1
            # Replace GitHub account if provided
            if (
                new_account
                and old_account != new_account
                and replace_in_file(abs_filepath, old_account, new_account)
            ):
                updated += 1

    print(f"✅ Updated {updated} references in template files")


def main():
    """Main bootstrap stage 1 process"""
    print("🚀 Augint Library Bootstrap - Stage 1")
    print("=====================================\n")

    # Change to project root directory for consistent execution
    original_cwd = os.getcwd()
    os.chdir(PROJECT_ROOT)

    try:
        # Step 1: Parse git remote
        account, repo = parse_git_remote()
        if not account or not repo:
            print("❌ Could not detect GitHub repository info from git remote")
            print("Please ensure you're in a git repository with a GitHub remote")
            sys.exit(1)

        print(f"📦 Project: {account}/{repo}")
        module_name = repo.replace("-", "_")
        print(f"🐍 Module name: {module_name}\n")

        # Step 2: Create .env file
        create_env_file(account, repo)

        # Step 3: Generate optimized CLAUDE.md
        print("\n📝 Generating optimized CLAUDE.md...")
        generate_claude_md(repo, module_name)

        # Step 4: Customize template
        print("\n🔧 Customizing template files...")
        customize_template("augint-library", repo, "augint_library", module_name, "svange", account)

        # Step 5: Clear changelog for new project
        print("\n📝 Clearing changelog...")
        clear_changelog()

        # Step 6: Replace LICENSE file
        print("\n📄 Replacing LICENSE with template...")
        replace_license()

        # Step 7: Reset version to 0.0.0 for new projects
        # Try multiple version patterns that might exist
        version_patterns = [
            '"1.26.0"',
            '"1.25.0"',
            '"1.24.0"',
            '"1.23.0"',
            '"1.22.0"',
            '"1.21.0"',
            '"1.20.0"',
        ]

        for pattern in version_patterns:
            if replace_in_file("pyproject.toml", f"version = {pattern}", 'version = "0.0.0"'):
                print(f"✅ Reset version from {pattern} to 0.0.0")
                break

        for pattern in version_patterns:
            if replace_in_file(
                f"src/{module_name}/__init__.py",
                f"__version__ = {pattern}",
                '__version__ = "0.0.0"',
            ):
                print(f"✅ Reset __version__ from {pattern} to 0.0.0")
                break

        # Step 8: Validate replacements
        validate_replacements("augint-library", "augint_library")

        # Step 9: Show next steps
        print("\n" + "=" * 50)
        print("✅ Stage 1 Bootstrap Complete!")
        print("=" * 50)
        print("\n📋 Next Steps:\n")
        print("1. Add your GitHub token to .env file")
        print("   - Generate at: https://github.com/settings/tokens")
        print("   - Needs: repo, workflow permissions\n")

        print("2. Install dependencies:")
        print("   poetry install")
        print("   .venv\\Scripts\\activate  # Windows")
        print("   # or: source .venv/bin/activate  # Unix/Mac\n")

        print("3. Create AWS pipeline resources:")
        print(f"   sam pipeline bootstrap --stage {repo}-testing")
        print("   - Follow the interactive prompts")
        print("   - Use GitHub Actions as the CI/CD provider")
        print(f"   - Repository: {account}/{repo}\n")

        print("4. Run Stage 2 bootstrap to complete setup:")
        print("   python scripts/bootstrap-stage2.py\n")

        print("📋 Commands to run between stages:")
        print("─" * 35)
        print("poetry install")
        print(".venv\\Scripts\\activate")
        print(f"sam pipeline bootstrap --stage {repo}-testing")
        print("python scripts/bootstrap-stage2.py")
        print("─" * 35)
    finally:
        # Restore original working directory
        os.chdir(original_cwd)


if __name__ == "__main__":
    main()
