#!/usr/bin/env python3
"""
GitHub Metrics Tracker for Novyx Core
Polls GitHub API for stars, forks, issues, and ingests as artifacts

Usage:
    python tools/github_metrics.py
    python tools/github_metrics.py --baseline  # Set initial baseline
    python tools/github_metrics.py --compare   # Compare to baseline

Requirements:
    - requests library (pre-installed)
    - GitHub repo: novyxlabs/novyx-core
"""

import json
import sys
from datetime import datetime
from tools.util import calculate_hash_for_new_artifact
from pathlib import Path
from typing import Dict, Optional

try:
    import requests
except ImportError:
    print("⚠️  'requests' library not found. Install with: pip install requests")
    sys.exit(1)

# Configuration
REPO_OWNER = "novyxlabs"
REPO_NAME = "novyx-core"
API_BASE = "https://api.github.com"
METRICS_DIR = Path(__file__).parent.parent / "memory" / "strategy" / "metrics"
BASELINE_FILE = METRICS_DIR / "baseline.json"


def fetch_repo_stats() -> Dict:
    """Fetch repository statistics from GitHub API."""
    url = f"{API_BASE}/repos/{REPO_OWNER}/{REPO_NAME}"
    
    try:
        print(f"📡 Fetching stats from GitHub API...")
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        data = response.json()
        
        stats = {
            "stars": data.get("stargazers_count", 0),
            "forks": data.get("forks_count", 0),
            "watchers": data.get("subscribers_count", 0),
            "open_issues": data.get("open_issues_count", 0),
            "size_kb": data.get("size", 0),
            "created_at": data.get("created_at"),
            "updated_at": data.get("updated_at"),
            "pushed_at": data.get("pushed_at"),
            "language": data.get("language"),
            "topics": data.get("topics", [])
        }
        
        print(f"✅ Fetched: {stats['stars']} ⭐ | {stats['forks']} 🍴 | {stats['open_issues']} 📋")
        return stats
        
    except requests.RequestException as e:
        print(f"❌ GitHub API error: {e}")
        sys.exit(1)


def fetch_traffic_stats() -> Optional[Dict]:
    """
    Fetch traffic stats (requires authentication).
    Returns None if unauthorized (expected for public use).
    """
    url = f"{API_BASE}/repos/{REPO_OWNER}/{REPO_NAME}/traffic/views"
    
    try:
        response = requests.get(url, timeout=10)
        if response.status_code == 403:
            # Expected for unauthenticated requests
            return None
        response.raise_for_status()
        return response.json()
    except requests.RequestException:
        return None


def calculate_growth(current: Dict, baseline: Dict) -> Dict:
    """Calculate growth metrics compared to baseline."""
    growth = {
        "stars_delta": current["stars"] - baseline["stars"],
        "forks_delta": current["forks"] - baseline["forks"],
        "stars_growth_pct": 0.0,
        "forks_growth_pct": 0.0
    }
    
    if baseline["stars"] > 0:
        growth["stars_growth_pct"] = (growth["stars_delta"] / baseline["stars"]) * 100
    
    if baseline["forks"] > 0:
        growth["forks_growth_pct"] = (growth["forks_delta"] / baseline["forks"]) * 100
    
    return growth


def save_baseline(stats: Dict):
    """Save current stats as baseline for future comparisons."""
    METRICS_DIR.mkdir(parents=True, exist_ok=True)
    
    baseline = {
        "@context": "https://novyx.ai/schemas/v1",
        "@type": "MetricsBaseline",
        "uuid": f"github_baseline_{datetime.now().strftime('%Y%m%d')}",
        "novyx:ingestedAt": datetime.now().isoformat(),
        "repo": f"{REPO_OWNER}/{REPO_NAME}",
        "stats": stats,
        "timestamp": datetime.now().isoformat()
    }
    
    # Generate integrity hash
    integrity_hash = calculate_hash_for_new_artifact(baseline)
    baseline["novyx:integrityHash"] = integrity_hash
    
    with open(BASELINE_FILE, 'w') as f:
        json.dump(baseline, f, indent=2)
    
    print(f"\n✅ Baseline saved: {BASELINE_FILE}")
    print(f"🔒 Integrity hash: {integrity_hash[:32]}...")


def load_baseline() -> Optional[Dict]:
    """Load baseline stats if exists."""
    if not BASELINE_FILE.exists():
        return None
    
    with open(BASELINE_FILE, 'r') as f:
        return json.load(f)


def ingest_as_artifact(stats: Dict, growth: Optional[Dict] = None):
    """Ingest metrics as Novyx artifact."""
    METRICS_DIR.mkdir(parents=True, exist_ok=True)
    
    timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S")
    artifact_id = f"github_metrics_{timestamp}"
    
    artifact = {
        "@context": "https://novyx.ai/schemas/v1",
        "@type": "MetricsSnapshot",
        "uuid": artifact_id,
        "novyx:ingestedAt": datetime.now().isoformat(),
        "repo": f"{REPO_OWNER}/{REPO_NAME}",
        "stats": stats,
        "growth": growth,
        "targets": {
            "stars_weekly": 50,
            "stars_total_goal": 500,
            "forks_goal": 100,
            "exit_criteria": "500 stars OR >20% MoM growth"
        }
    }
    
    # Generate integrity hash
    integrity_hash = calculate_hash_for_new_artifact(artifact)
    artifact["novyx:integrityHash"] = integrity_hash
    
    filepath = METRICS_DIR / f"{artifact_id}.jsonld"
    with open(filepath, 'w') as f:
        json.dump(artifact, f, indent=2)
    
    print(f"\n📥 Metrics ingested: {filepath}")
    print(f"🔒 Integrity hash: {integrity_hash[:32]}...")
    
    return filepath


def display_report(stats: Dict, baseline: Optional[Dict], growth: Optional[Dict]):
    """Display formatted metrics report."""
    print("\n" + "="*70)
    print("📊 NOVYX CORE GITHUB METRICS REPORT")
    print("="*70)
    
    print(f"\n🎯 Repository: {REPO_OWNER}/{REPO_NAME}")
    print(f"📅 Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S UTC')}")
    
    print("\n📈 Current Stats:")
    print(f"   ⭐ Stars:         {stats['stars']:,}")
    print(f"   🍴 Forks:         {stats['forks']:,}")
    print(f"   👁️  Watchers:      {stats['watchers']:,}")
    print(f"   📋 Open Issues:   {stats['open_issues']:,}")
    print(f"   💾 Size:          {stats['size_kb']:,} KB")
    
    if baseline and growth:
        print("\n📊 Growth Since Baseline:")
        print(f"   ⭐ Stars Delta:   {growth['stars_delta']:+d} ({growth['stars_growth_pct']:+.1f}%)")
        print(f"   🍴 Forks Delta:   {growth['forks_delta']:+d} ({growth['forks_growth_pct']:+.1f}%)")
        
        baseline_date = baseline.get('timestamp', 'Unknown')
        print(f"   📅 Baseline:      {baseline_date}")
    
    print("\n🎯 Targets (2026 Roadmap):")
    print("   • Weekly Goal:    +50 stars/week")
    print("   • Total Goal:     500 stars (Q2 2026)")
    print("   • Exit Criteria:  500 stars OR >20% MoM growth")
    
    # Calculate progress
    if stats['stars'] > 0:
        progress_pct = (stats['stars'] / 500) * 100
        progress_bar = "█" * int(progress_pct / 5) + "░" * (20 - int(progress_pct / 5))
        print(f"\n📊 Progress to 500 Stars:")
        print(f"   [{progress_bar}] {progress_pct:.1f}%")
        print(f"   Remaining: {500 - stats['stars']} stars")
    
    print("\n" + "="*70)


def main():
    """Main execution."""
    import sys
    
    mode = sys.argv[1] if len(sys.argv) > 1 else "track"
    
    if mode == "--baseline":
        print("🔧 Setting baseline metrics...")
        stats = fetch_repo_stats()
        save_baseline(stats)
        print("\n✅ Baseline set! Run without --baseline to track growth.")
        
    elif mode == "--compare":
        print("📊 Comparing current metrics to baseline...")
        stats = fetch_repo_stats()
        baseline = load_baseline()
        
        if not baseline:
            print("\n⚠️  No baseline found. Run with --baseline first.")
            sys.exit(1)
        
        growth = calculate_growth(stats, baseline["stats"])
        display_report(stats, baseline, growth)
        ingest_as_artifact(stats, growth)
        
    else:  # default: track
        print("📈 Tracking current GitHub metrics...")
        stats = fetch_repo_stats()
        baseline = load_baseline()
        
        growth = None
        if baseline:
            growth = calculate_growth(stats, baseline["stats"])
        
        display_report(stats, baseline, growth)
        ingest_as_artifact(stats, growth)
        
        if not baseline:
            print("\n💡 Tip: Run with --baseline to set initial baseline for growth tracking")


if __name__ == "__main__":
    main()
