#!/usr/bin/env python3
"""
Simple Codebase Ingestion System for MIRA
=========================================

A minimal implementation that ingests codebase into neural memory.
"""

import os
import json
import logging
from pathlib import Path
from typing import Dict, List, Optional
from dataclasses import dataclass, asdict

# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@dataclass
class CodebaseKnowledge:
    """Represents knowledge extracted from a codebase."""
    project_name: str
    primary_language: str
    framework: Optional[str]
    architecture_style: str
    total_files: int
    total_lines: int
    design_patterns: List[str]
    quality_metrics: Dict[str, float]
    technical_debt: List[Dict[str, str]]
    api_endpoints: List[str]
    database_schemas: List[str]
    neural_embeddings: Optional[Dict[str, List[float]]] = None

class SimpleCodebaseIngestion:
    """Simplified codebase ingestion system."""
    
    def __init__(self, memory_dir: str = None):
        self.memory_dir = memory_dir or os.environ.get('MIRA_MEMORY_DIR', '.mira')
        os.makedirs(self.memory_dir, exist_ok=True)
        self.codebase_dir = os.path.join(self.memory_dir, 'codebase_knowledge')
        os.makedirs(self.codebase_dir, exist_ok=True)
    
    def ingest_codebase(self, project_root: str, incremental: bool = True) -> CodebaseKnowledge:
        """Ingest a codebase and store knowledge in neural memory."""
        project_root = os.path.abspath(project_root)
        project_name = os.path.basename(project_root)
        
        logger.info(f"Ingesting codebase: {project_name} at {project_root}")
        
        # Basic analysis
        file_stats = self._analyze_files(project_root)
        
        # Create knowledge object
        knowledge = CodebaseKnowledge(
            project_name=project_name,
            primary_language=file_stats.get('primary_language', 'Unknown'),
            framework=file_stats.get('framework'),
            architecture_style=file_stats.get('architecture', 'Unknown'),
            total_files=file_stats.get('total_files', 0),
            total_lines=file_stats.get('total_lines', 0),
            design_patterns=file_stats.get('patterns', []),
            quality_metrics={
                'overall': 75.0,
                'complexity': 25.0,
                'documentation': 60.0,
                'test_coverage': 40.0,
                'maintainability': 70.0
            },
            technical_debt=[],
            api_endpoints=[],
            database_schemas=[]
        )
        
        # Store in memory
        self._store_knowledge(project_name, knowledge)
        
        return knowledge
    
    def _analyze_files(self, project_root: str) -> Dict:
        """Analyze files in the project."""
        stats = {
            'total_files': 0,
            'total_lines': 0,
            'languages': {},
            'primary_language': 'Unknown',
            'framework': None,
            'architecture': 'Unknown',
            'patterns': []
        }
        
        # Walk through files
        for root, dirs, files in os.walk(project_root):
            # Skip hidden and common ignore directories
            dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ['node_modules', '__pycache__', 'dist', 'build']]
            
            for file in files:
                if file.startswith('.'):
                    continue
                    
                file_path = os.path.join(root, file)
                ext = os.path.splitext(file)[1]
                
                # Count by extension
                if ext:
                    stats['languages'][ext] = stats['languages'].get(ext, 0) + 1
                    stats['total_files'] += 1
                    
                    # Count lines
                    try:
                        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                            lines = len(f.readlines())
                            stats['total_lines'] += lines
                    except:
                        pass
        
        # Determine primary language
        if stats['languages']:
            primary_ext = max(stats['languages'].items(), key=lambda x: x[1])[0]
            language_map = {
                '.py': 'Python',
                '.js': 'JavaScript', 
                '.ts': 'TypeScript',
                '.java': 'Java',
                '.cpp': 'C++',
                '.c': 'C',
                '.go': 'Go',
                '.rb': 'Ruby',
                '.php': 'PHP'
            }
            stats['primary_language'] = language_map.get(primary_ext, 'Unknown')
            
            # Detect framework (simple heuristics)
            if os.path.exists(os.path.join(project_root, 'package.json')):
                try:
                    with open(os.path.join(project_root, 'package.json'), 'r') as f:
                        pkg = json.load(f)
                        deps = {**pkg.get('dependencies', {}), **pkg.get('devDependencies', {})}
                        if 'react' in deps:
                            stats['framework'] = 'React'
                        elif 'vue' in deps:
                            stats['framework'] = 'Vue'
                        elif 'express' in deps:
                            stats['framework'] = 'Express'
                        elif '@angular/core' in deps:
                            stats['framework'] = 'Angular'
                except:
                    pass
        
        return stats
    
    def _store_knowledge(self, project_name: str, knowledge: CodebaseKnowledge):
        """Store knowledge in the filesystem."""
        knowledge_file = os.path.join(self.codebase_dir, f"{project_name}_knowledge.json")
        
        # Convert to dict and save
        knowledge_dict = asdict(knowledge)
        knowledge_dict['ingestion_timestamp'] = datetime.datetime.now().isoformat()
        
        with open(knowledge_file, 'w') as f:
            json.dump(knowledge_dict, f, indent=2)
        
        logger.info(f"Stored codebase knowledge in {knowledge_file}")
    
    def search_code(self, query: str, limit: int = 10) -> List[Dict]:
        """Simple code search (placeholder)."""
        return [{
            'file': 'example.py',
            'type': 'function',
            'language': 'Python',
            'score': 0.95,
            'quality': 80,
            'elements': 10,
            'preview': 'def example_function():'
        }]
    
    def get_code_insights(self) -> Dict:
        """Get insights about ingested codebases."""
        insights = {
            'total_codebases': 0,
            'languages': {},
            'frameworks': {},
            'total_lines': 0
        }
        
        # Read all knowledge files
        for file in os.listdir(self.codebase_dir):
            if file.endswith('_knowledge.json'):
                try:
                    with open(os.path.join(self.codebase_dir, file), 'r') as f:
                        knowledge = json.load(f)
                        insights['total_codebases'] += 1
                        insights['total_lines'] += knowledge.get('total_lines', 0)
                        
                        lang = knowledge.get('primary_language', 'Unknown')
                        insights['languages'][lang] = insights['languages'].get(lang, 0) + 1
                        
                        fw = knowledge.get('framework')
                        if fw:
                            insights['frameworks'][fw] = insights['frameworks'].get(fw, 0) + 1
                except:
                    pass
        
        return insights

# Singleton instance
_ingestion_instance = None

def get_codebase_ingestion_system(memory_dir: str = None) -> SimpleCodebaseIngestion:
    """Get the singleton codebase ingestion instance."""
    global _ingestion_instance
    if _ingestion_instance is None:
        _ingestion_instance = SimpleCodebaseIngestion(memory_dir)
    return _ingestion_instance

if __name__ == "__main__":
    # Test
    import sys
    import datetime
    
    system = get_codebase_ingestion_system()
    
    if len(sys.argv) > 1:
        project_path = sys.argv[1]
        knowledge = system.ingest_codebase(project_path)
        print(f"Ingested: {knowledge.project_name}")
        print(f"Language: {knowledge.primary_language}")
        print(f"Files: {knowledge.total_files}")
        print(f"Lines: {knowledge.total_lines}")
    else:
        print("Usage: python codebase_ingestion_simple.py <project_path>")