#!/usr/bin/env python3
"""
PRD GENERATOR - Automatic PRD Creation
======================================
Generates PRDs based on codebase analysis, gaps, and evolution history.
"""

import os
import json
import random
import logging
from datetime import datetime
from pathlib import Path
from typing import List, Dict, Optional, Any

logger = logging.getLogger(__name__)

GENESIS_ROOT = Path(__file__).parent.parent.parent


class PRDGenerator:
    """
    Generates PRDs automatically based on:
    - Codebase gap analysis
    - Previous execution outcomes
    - Surprise events (learning triggers)
    - Random exploration (novelty)
    """

    # PRD categories
    CATEGORIES = [
        'capability',
        'integration',
        'optimization',
        'testing',
        'documentation',
        'infrastructure',
        'meta',  # PRDs about PRDs
    ]

    # PRD templates for each category
    TEMPLATES = {
        'capability': """# PRD: {title}
## GENESIS-CAP-{id} | Capability

### Vision Statement
{vision}

### Success Metrics
| Metric | Target | Measurement |
|--------|--------|-------------|
| Implementation Complete | 100% | All stories done |
| Test Coverage | > 80% | pytest --cov |
| No Regressions | 0 | Existing tests pass |

### Atomic Stories

#### Story 1: {story1_title}
- **As** a Genesis component, **I need** {story1_need}, **So that** {story1_benefit}
- **Acceptance Criteria**:
  - [ ] {story1_ac1}
  - [ ] {story1_ac2}
  - [ ] Tests written and passing

#### Story 2: {story2_title}
- **As** a Genesis component, **I need** {story2_need}, **So that** {story2_benefit}
- **Acceptance Criteria**:
  - [ ] {story2_ac1}
  - [ ] {story2_ac2}
  - [ ] Tests written and passing

### Test Requirements
- Black-box tests for external behavior
- White-box tests for internal logic
- Integration tests with existing components

---
*Generated by Genesis Evolution Engine*
*Cycle: {cycle_id} | {timestamp}*
""",
        'meta': """# PRD: {title}
## GENESIS-META-{id} | Meta-Evolution

### Vision Statement
{vision}

### Pattern Observed
{pattern}

### Improvement Target
{improvement}

### Implementation
{implementation}

### Success Metrics
| Metric | Target |
|--------|--------|
| PRD Quality Improved | Measurable |
| Cycle Time Reduced | -10% |

---
*Generated by Genesis Evolution Engine (Meta-Layer)*
*Cycle: {cycle_id} | {timestamp}*
""",
    }

    # Gap analysis targets
    GAP_TARGETS = [
        ('core/memory', 'memory_enhancement', 'Enhanced memory persistence and retrieval'),
        ('core/monitoring', 'monitoring_improvement', 'Better system observability'),
        ('skills/', 'new_skill', 'New capability skill'),
        ('tools/', 'tool_enhancement', 'Tool improvement or new tool'),
        ('tests/', 'test_coverage', 'Improved test coverage'),
        ('core/evolution', 'evolution_enhancement', 'Evolution system improvement'),
    ]

    def __init__(self, output_dir: Optional[Path] = None):
        """Initialize PRD generator."""
        self.output_dir = output_dir or (GENESIS_ROOT / "docs" / "plans" / "generated")
        self.output_dir.mkdir(parents=True, exist_ok=True)
        self._prd_count = 0

    def generate(
        self,
        cycle_id: int,
        category: Optional[str] = None,
        based_on_surprise: Optional[Dict] = None,
        max_prds: int = 3
    ) -> List[Path]:
        """
        Generate PRDs for this evolution cycle.

        Args:
            cycle_id: Current evolution cycle
            category: Specific category (or random)
            based_on_surprise: Surprise event to base PRD on
            max_prds: Maximum PRDs to generate

        Returns:
            List of paths to generated PRD files
        """
        generated = []

        for i in range(max_prds):
            # Select category
            if category:
                cat = category
            elif based_on_surprise and i == 0:
                cat = 'meta'  # First PRD responds to surprise
            else:
                cat = random.choice(self.CATEGORIES)

            # Generate PRD
            prd_path = self._generate_single(cycle_id, cat, based_on_surprise if i == 0 else None)
            if prd_path:
                generated.append(prd_path)

            # Random chance to stop early (simulates natural variation)
            if random.random() < 0.3:
                break

        logger.info(f"Generated {len(generated)} PRDs for cycle {cycle_id}")
        return generated

    def _generate_single(
        self,
        cycle_id: int,
        category: str,
        surprise_context: Optional[Dict] = None
    ) -> Optional[Path]:
        """Generate a single PRD."""
        self._prd_count += 1
        prd_id = f"{cycle_id:03d}_{self._prd_count:03d}"
        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        # Generate content based on category
        if category == 'meta' and surprise_context:
            content = self._generate_meta_prd(prd_id, cycle_id, timestamp, surprise_context)
        elif category == 'capability':
            content = self._generate_capability_prd(prd_id, cycle_id, timestamp)
        else:
            content = self._generate_generic_prd(prd_id, cycle_id, timestamp, category)

        # Write to file
        filename = f"PRD_{prd_id}_{category}.md"
        filepath = self.output_dir / filename

        try:
            filepath.write_text(content)
            logger.info(f"Created PRD: {filename}")
            return filepath
        except Exception as e:
            logger.error(f"Failed to write PRD: {e}")
            return None

    def _generate_capability_prd(self, prd_id: str, cycle_id: int, timestamp: str) -> str:
        """Generate a capability PRD."""
        # Pick a gap target
        target = random.choice(self.GAP_TARGETS)
        path_prefix, cap_type, description = target

        # Generate unique content
        titles = [
            f"Enhanced {cap_type.replace('_', ' ').title()}",
            f"Improved {cap_type.replace('_', ' ').title()} System",
            f"Advanced {cap_type.replace('_', ' ').title()} Module",
        ]
        title = random.choice(titles)

        return self.TEMPLATES['capability'].format(
            title=title,
            id=prd_id,
            vision=f"Implement {description.lower()} to enhance Genesis capabilities.",
            story1_title=f"Core {cap_type.replace('_', ' ').title()} Implementation",
            story1_need=f"implement the core {cap_type.replace('_', ' ')} functionality",
            story1_benefit="Genesis can perform this capability reliably",
            story1_ac1=f"Core {cap_type} module created",
            story1_ac2="Unit tests written and passing",
            story2_title=f"{cap_type.replace('_', ' ').title()} Integration",
            story2_need=f"integrate {cap_type.replace('_', ' ')} with existing systems",
            story2_benefit="the capability works seamlessly with Genesis",
            story2_ac1="Integration points identified and connected",
            story2_ac2="Integration tests passing",
            cycle_id=cycle_id,
            timestamp=timestamp,
        )

    def _generate_meta_prd(
        self,
        prd_id: str,
        cycle_id: int,
        timestamp: str,
        surprise_context: Dict
    ) -> str:
        """Generate a meta-PRD based on surprise event."""
        return self.TEMPLATES['meta'].format(
            title="Evolution System Self-Improvement",
            id=prd_id,
            vision="Improve the PRD generation and execution system based on observed surprise patterns.",
            pattern=f"Surprise detected with score {surprise_context.get('surprise_score', 0):.3f}: {surprise_context.get('trigger_reason', 'unknown')}",
            improvement="Adjust expectations and execution parameters to reduce future surprises of this type.",
            implementation="""
1. Update expectation baselines in surprise detector
2. Adjust timeout and resource allocation
3. Add specific handling for this surprise pattern
4. Create regression tests for this scenario
""",
            cycle_id=cycle_id,
            timestamp=timestamp,
        )

    def _generate_generic_prd(
        self,
        prd_id: str,
        cycle_id: int,
        timestamp: str,
        category: str
    ) -> str:
        """Generate a generic PRD for any category."""
        return f"""# PRD: {category.title()} Enhancement
## GENESIS-{category.upper()[:3]}-{prd_id} | {category.title()}

### Vision Statement
Improve Genesis {category} capabilities through systematic enhancement.

### Scope
Category: {category}
Generated: Cycle {cycle_id}

### Stories
1. Analysis and planning
2. Core implementation
3. Testing and verification

### Success Criteria
- Implementation complete
- Tests passing
- No regressions

---
*Generated by Genesis Evolution Engine*
*Cycle: {cycle_id} | {timestamp}*
"""

    def get_recent_prds(self, limit: int = 10) -> List[Path]:
        """Get recently generated PRDs."""
        prds = list(self.output_dir.glob("PRD_*.md"))
        prds.sort(key=lambda p: p.stat().st_mtime, reverse=True)
        return prds[:limit]

    def get_statistics(self) -> Dict[str, Any]:
        """Get PRD generation statistics."""
        prds = list(self.output_dir.glob("PRD_*.md"))

        categories = {}
        for prd in prds:
            parts = prd.stem.split('_')
            if len(parts) >= 3:
                cat = parts[-1]
                categories[cat] = categories.get(cat, 0) + 1

        return {
            'total_prds': len(prds),
            'categories': categories,
            'session_generated': self._prd_count,
        }


if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)

    generator = PRDGenerator()

    # Generate some PRDs
    prds = generator.generate(cycle_id=1, max_prds=3)

    print(f"\nGenerated {len(prds)} PRDs:")
    for p in prds:
        print(f"  - {p.name}")

    print(f"\nStatistics: {generator.get_statistics()}")
