"""Protocol generator core logic."""

import shutil
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, cast

from cokodo_agent.config import AI_TOOLS, TECH_STACKS


def generate_protocol(
    source_path: Path,
    target_path: Path,
    config: Dict[str, Any],
    force: bool = False,
) -> None:
    """
    Generate .agent protocol in target directory.

    Args:
        source_path: Path to source protocol files
        target_path: Target project directory
        config: Configuration dictionary from prompts
        force: Overwrite existing .agent if True
    """

    agent_dir = target_path / ".agent"

    # Remove existing if force
    if agent_dir.exists():
        if force:
            shutil.rmtree(agent_dir)
        else:
            raise FileExistsError(f".agent already exists at {agent_dir}")

    # Copy protocol files
    shutil.copytree(source_path, agent_dir)

    # Customize project files
    _customize_context(agent_dir, config)
    _customize_tech_stack(agent_dir, config)

    # Generate AI tool adapters
    _generate_adapters(target_path, config)


def _customize_context(agent_dir: Path, config: Dict[str, Any]) -> None:
    """Customize project/context.md with user input."""

    context_file = agent_dir / "project" / "context.md"

    content = f"""# Project Context

## Project Name

{config.get('project_name', 'Unnamed Project')}

## Description

{config.get('description', '[TODO: Add project description]')}

## Current Status

[TODO: Describe current development status]

## Key Features

[TODO: List main features]

## Business Rules

[TODO: Document important business logic]

---

*Generated by cokodo-agent on {datetime.now().strftime('%Y-%m-%d')}*
"""

    context_file.write_text(content, encoding="utf-8")


def _customize_tech_stack(agent_dir: Path, config: Dict[str, Any]) -> None:
    """Customize project/tech-stack.md with user input."""

    tech_stack_file = agent_dir / "project" / "tech-stack.md"

    stack_key = config.get("tech_stack", "other")
    stack_name = TECH_STACKS.get(stack_key, "Other")

    # Stack-specific recommendations
    stack_recommendations = {
        "python": """
## Recommended Tools

- Package Manager: uv / pip
- Linting: ruff
- Testing: pytest
- Type Checking: mypy
""",
        "rust": """
## Recommended Tools

- Package Manager: cargo
- Linting: clippy
- Testing: cargo test
- Formatting: rustfmt
""",
        "qt": """
## Recommended Tools

- Build System: CMake / qmake
- IDE: Qt Creator
- Testing: Qt Test
""",
        "mixed": """
## Recommended Tools

### Python
- Package Manager: uv / pip
- Linting: ruff

### Rust
- Package Manager: cargo
- Linting: clippy
""",
    }

    recommendations = stack_recommendations.get(
        stack_key,
        """
## Recommended Tools

[TODO: Add your tooling recommendations]
""",
    )

    content = f"""# Tech Stack

## Primary Stack

{stack_name}

## Language Versions

[TODO: Specify versions, e.g., Python 3.11+, Rust 1.70+]

## Key Dependencies

[TODO: List main dependencies]

{recommendations}

## Development Environment

[TODO: Describe development setup]

---

*Generated by cokodo-agent on {datetime.now().strftime('%Y-%m-%d')}*
"""

    tech_stack_file.write_text(content, encoding="utf-8")


def _generate_adapters(target_path: Path, config: Dict[str, Any]) -> None:
    """Generate AI tool adapter files."""

    ai_tools = config.get("ai_tools", [])

    for tool_key in ai_tools:
        if tool_key not in AI_TOOLS:
            continue

        tool_info = AI_TOOLS[tool_key]

        # Skip if no file to generate (e.g., cokodo mode)
        if tool_info["file"] is None:
            continue

        # Handle Antigravity specially - creates rules directory
        if tool_key == "antigravity":
            _generate_antigravity_rules(target_path, config)
            continue

        adapter_file = target_path / cast(str, tool_info["file"])

        # Ensure parent directory exists
        adapter_file.parent.mkdir(parents=True, exist_ok=True)

        # Generate adapter content
        content = _get_adapter_content(tool_key, config)
        adapter_file.write_text(content, encoding="utf-8")


def _get_adapter_content(tool_key: str, config: Dict[str, Any]) -> str:
    """Get adapter file content for specific tool."""

    project_name = config.get("project_name", "Project")

    if tool_key == "cursor":
        return f"""# Cursor Rules for {project_name}

## Protocol Reference

This project uses AI Agent Collaboration Protocol.
Please read `.agent/start-here.md` first to establish context.

## Quick Reference

- Core rules: `.agent/core/core-rules.md`
- Coding guidelines: `.agent/core/instructions.md`
- Project context: `.agent/project/context.md`

## Key Principles

1. Follow UTF-8 encoding explicitly
2. Use forward slash `/` for paths
3. Test data must use `autotest_` prefix
4. No external CDN links

## Loading Priority

1. `.agent/start-here.md` (entry point)
2. `.agent/quick-reference.md` (cheat sheet)
3. `.agent/project/context.md` (project-specific)
"""

    elif tool_key == "copilot":
        return f"""# GitHub Copilot Instructions for {project_name}

## Protocol Reference

This project follows AI Agent Collaboration Protocol.
Reference: `.agent/start-here.md`

## Coding Standards

- Encoding: UTF-8 (explicit)
- Paths: Forward slash `/`
- Test prefix: `autotest_`
- No CDN links

## Key Files

- `.agent/core/core-rules.md` - Core principles
- `.agent/core/instructions.md` - Collaboration guidelines
- `.agent/project/context.md` - Project context
- `.agent/quick-reference.md` - Quick reference

## Before Coding

1. Read `.agent/project/context.md` for business context
2. Check `.agent/project/tech-stack.md` for tech decisions
3. Consult `.agent/core/workflows/bug-prevention.md` for known pitfalls
"""

    elif tool_key == "claude":
        return f"""# Claude Instructions for {project_name}

## Protocol

This project uses AI Agent Collaboration Protocol.
Start by reading `.agent/start-here.md`.

## Essential Documents

1. `.agent/quick-reference.md` - One-page cheat sheet
2. `.agent/core/core-rules.md` - Non-negotiable rules
3. `.agent/project/context.md` - Project context

## Rules

- Always use UTF-8 encoding
- Use forward slash for paths
- Test data prefix: `autotest_`
- No external CDN dependencies
"""

    return f"# AI Instructions for {project_name}\n\nSee `.agent/start-here.md`\n"


def _generate_antigravity_rules(target_path: Path, config: Dict[str, Any]) -> None:
    """Generate Google Antigravity rules directory."""

    agent_dir = target_path / ".agent"
    rules_dir = agent_dir / "rules"
    rules_dir.mkdir(exist_ok=True)

    project_name = config.get("project_name", "Project")

    # Core rules file mapping
    rule_mappings = {
        "core-rules.md": {
            "source": "core/core-rules.md",
            "title": "Core Rules",
            "activation": "Always On",
        },
        "instructions.md": {
            "source": "core/instructions.md",
            "title": "AI Collaboration Guidelines",
            "activation": "Always On",
        },
        "conventions.md": {
            "source": "core/conventions.md",
            "title": "Naming and Git Conventions",
            "activation": "Model Decision",
        },
        "security.md": {
            "source": "core/security.md",
            "title": "Security Development Standards",
            "activation": "Manual",
        },
    }

    # Create rule reference files
    for rule_name, rule_config in rule_mappings.items():
        target_file = rules_dir / rule_name
        content = f"""# {rule_config['title']}

> Activation Mode: {rule_config['activation']}

For detailed rules, please refer to:

@.agent/{rule_config['source']}
"""
        target_file.write_text(content, encoding="utf-8")

    # Create project context rule
    project_rule = rules_dir / "project-context.md"
    project_rule.write_text(
        """# Project Context

> Activation Mode: Always On

Project business context and tech stack information:

@.agent/project/context.md
@.agent/project/tech-stack.md
@.agent/project/known-issues.md
""",
        encoding="utf-8",
    )

    # Create README for rules directory
    readme = rules_dir / "README.md"
    readme.write_text(
        f"""# Antigravity Rules for {project_name}

This directory contains workspace rules for Google Antigravity.

## Rules Description

| File | Description | Activation Mode |
|------|-------------|-----------------|
| `core-rules.md` | Core development rules | Always On |
| `instructions.md` | AI collaboration guidelines | Always On |
| `conventions.md` | Naming and Git conventions | Model Decision |
| `security.md` | Security development standards | Manual (@security) |
| `project-context.md` | Project context | Always On |

## Activation Modes

- **Always On**: Always applied
- **Manual**: Manually activate using @rule-name in conversation
- **Model Decision**: Model decides whether to apply based on task
- **Glob**: Applied when matching specific file types

## More Information

See [Google Antigravity Rules Documentation](https://antigravity.google/docs/rules-workflows)

---

*Generated by cokodo-agent on {datetime.now().strftime('%Y-%m-%d')}*
""",
        encoding="utf-8",
    )
