"""Universal AGENTS.md generator with platform-specific overlays.

AGENTS.md is a Linux Foundation open standard supported by Cursor,
Codex, Amp, Jules, Factory, and others. This module generates
platform-universal content with optional platform-specific overlays.
"""

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from mirdan.cli.detect import DetectedProject
    from mirdan.core.quality_standards import QualityStandards


class AgentsMDGenerator:
    """Generates AGENTS.md files for cross-platform agent configuration.

    The generated file contains:
    - Universal quality rules (work on all platforms)
    - Platform-specific overlays (Cursor, Claude Code, etc.)
    - Language-specific guidance
    """

    def __init__(
        self,
        standards: QualityStandards | None = None,
    ) -> None:
        self._standards = standards

    def generate(
        self,
        detected: DetectedProject,
        platform: str = "universal",
        languages: list[str] | None = None,
    ) -> str:
        """Generate AGENTS.md content.

        Args:
            detected: Detected project metadata.
            platform: Target platform ("universal", "cursor", "claude-code").
            languages: Optional list of languages to generate sections for (workspace mode).

        Returns:
            AGENTS.md content string.
        """
        sections = [
            self._header(),
            self._quality_rules(),
            self._language_section(detected, languages=languages),
            self._security_section(),
            self._workflow_section(platform),
        ]

        # Platform-specific overlay
        if platform == "cursor":
            sections.append(self._cursor_overlay(detected))
        elif platform == "claude-code":
            sections.append(self._claude_code_overlay(detected))

        return "\n".join(sections)

    def generate_and_write(
        self,
        output_path: Path,
        detected: DetectedProject,
        platform: str = "universal",
        languages: list[str] | None = None,
    ) -> Path:
        """Generate and write AGENTS.md to disk.

        Args:
            output_path: Path to write the file.
            detected: Detected project metadata.
            platform: Target platform.
            languages: Optional list of languages to generate sections for (workspace mode).

        Returns:
            Path to the written file.
        """
        output_path.parent.mkdir(parents=True, exist_ok=True)
        content = self.generate(detected, platform, languages=languages)
        output_path.write_text(content)
        return output_path

    # ------------------------------------------------------------------
    # Universal sections
    # ------------------------------------------------------------------

    def _header(self) -> str:
        """Generate the AGENTS.md header."""
        return """# AGENTS.md — mirdan Quality Configuration

> Auto-generated by mirdan. Do not edit manually — regenerate with `mirdan init --upgrade`.

This file configures AI coding agents for quality enforcement using the
[AGENTS.md open standard](https://github.com/anthropics/agents-md).
"""

    def _quality_rules(self) -> str:
        """Generate the universal quality rules section."""
        return """## AI Code Quality Rules

These rules apply to all AI agents working in this codebase:

| Rule | Description | Severity |
|------|-------------|----------|
| AI001 | No placeholder code (raise NotImplementedError, pass with TODO) | Error |
| AI002 | No hallucinated imports (verify all imports exist) | Warning |
| AI003 | No over-engineering (unnecessary abstractions) | Warning |
| AI004 | No duplicate code blocks | Warning |
| AI005 | Consistent error handling patterns | Warning |
| AI006 | No unnecessary heavy imports | Info |
| AI007 | No security theater (hash() on passwords) | Error |
| AI008 | No injection vulnerabilities | Error |
"""

    def _language_section(
        self,
        detected: DetectedProject,
        languages: list[str] | None = None,
    ) -> str:
        """Generate language-specific guidance.

        When a QualityStandards instance is available, includes
        language-specific rules from the standards database.

        Args:
            detected: Detected project metadata.
            languages: Optional list of languages (workspace mode). When provided,
                generates a section for each language.
        """
        langs = languages or (
            [detected.primary_language] if detected.primary_language else ["python"]
        )
        frameworks = detected.frameworks or []

        lines: list[str] = []
        for lang in langs:
            lines.append(f"## Language: {lang.title()}\n")
            lines.append(f"- Follow {lang} best practices and project conventions")
            lines.append("- Use type annotations where supported")
            lines.append("- Keep functions under 30 lines, files under 300 lines")
            lines.append("- Maximum nesting depth: 4 levels")

            if frameworks:
                lines.append(f"\n### Frameworks: {', '.join(frameworks)}")
                lines.extend(f"- Follow {fw} best practices and patterns" for fw in frameworks)

            # Include language standards if available
            if self._standards is not None:
                standards_data = self._standards.get_all_standards(language=lang, category="style")
                if standards_data:
                    lines.append(f"\n### {lang.title()} Standards")
                    for items in standards_data.values():
                        if isinstance(items, list):
                            for item in items[:5]:
                                if isinstance(item, dict):
                                    desc = item.get("description", item.get("message", ""))
                                    rule_id = item.get("id", "")
                                    if desc:
                                        if rule_id:
                                            entry = f"- **{rule_id}**: {desc}"
                                        else:
                                            entry = f"- {desc}"
                                        lines.append(entry)
                                elif isinstance(item, str):
                                    lines.append(f"- {item}")

            lines.append("")

        return "\n".join(lines)

    def _security_section(self) -> str:
        """Generate security standards section."""
        return """## Security Standards

### Critical (Must Fix)
- No hardcoded secrets or API keys (SEC001)
- No SQL injection via string concatenation (SEC002)
- No command injection via unsanitized input (SEC003)
- No path traversal vulnerabilities (SEC004)
- No insecure deserialization (SEC005)

### Important (Should Fix)
- Use HTTPS for all external requests (SEC006)
- Validate and sanitize all user input (SEC007)
- Use parameterized queries for database operations (SEC008)
- Apply principle of least privilege (SEC009)
- Log security events without exposing sensitive data (SEC010)
- No Cypher injection — use parameterized graph queries (SEC011)
- No Gremlin injection — use parameterized traversals (SEC012)
- Use bcrypt or argon2 for password hashing, never MD5/SHA (SEC013)
- No vulnerable dependencies — upgrade packages with known CVEs (SEC014)
"""

    def _workflow_section(self, platform: str) -> str:
        """Generate quality workflow section."""
        return """## Quality Workflow

1. **Before writing code**: Call `enhance_prompt` for quality requirements
2. **After writing code**: Call `validate_code_quality` to check
3. **Fix all errors** before committing or marking complete
4. **Security-sensitive code** requires `check_security=true` validation
"""

    # ------------------------------------------------------------------
    # Platform-specific overlays
    # ------------------------------------------------------------------

    def _cursor_overlay(self, detected: DetectedProject) -> str:
        """Generate Cursor-specific overlay."""
        return """## Cursor-Specific Configuration

### Background Agent
- Run mirdan validation on all changed files before committing
- Use `validate_quick` for real-time feedback during editing
- Check BugBot security standards for PR reviews

### Integration
- mirdan .mdc rules are in `.cursor/rules/`
- BugBot security config is in `.cursor/BUGBOT.md`
"""

    def _claude_code_overlay(self, detected: DetectedProject) -> str:
        """Generate Claude Code-specific overlay."""
        return """## Claude Code-Specific Configuration

### Hook Integration
- PreToolUse: Ensures `enhance_prompt` is called before writing code
- PostToolUse: Runs quick validation after file edits
- Stop: Full validation before task completion

### MCP Tools
- `mcp__mirdan__enhance_prompt`: Get quality requirements for a task
- `mcp__mirdan__validate_code_quality`: Validate written code
- `mcp__mirdan__validate_quick`: Fast security-only validation
- `mcp__mirdan__get_quality_standards`: Language/framework standards

### Skills & Agents
- `/code`: Quality-guided code generation
- `/debug`: Quality-aware debugging
- `/review`: Code review with quality standards
- `/plan`: Quality-gated implementation planning
- `/quality`: On-demand quality validation and trends
- `/scan`: Convention scanning and codebase analysis
- `/gate`: Quality gate check before commits or task completion
"""


def generate_root_agents_md(
    project_dir: Path,
    detected: DetectedProject,
    standards: QualityStandards | None = None,
    platform: str = "universal",
    languages: list[str] | None = None,
) -> Path:
    """Convenience function to generate root AGENTS.md.

    Args:
        project_dir: Project root directory.
        detected: Detected project metadata.
        standards: Optional QualityStandards instance.
        platform: Target platform.
        languages: Optional list of languages to generate sections for (workspace mode).

    Returns:
        Path to the generated AGENTS.md file.
    """
    generator = AgentsMDGenerator(standards=standards)
    agents_path = project_dir / "AGENTS.md"
    return generator.generate_and_write(agents_path, detected, platform, languages=languages)
