package main

import (
	"flag"
	"fmt"
	"log"
	"os"
)

func main() {
	sourceDir := flag.String("source", "", "Path to Go source root (e.g., ../../golang/nats-server)")
	dbPath := flag.String("db", "", "Path to SQLite database file (e.g., ../../porting.db)")
	schemaPath := flag.String("schema", "", "Path to SQL schema file (e.g., ../../porting-schema.sql)")
	mode := flag.String("mode", "full", "Analysis mode: 'full' (default) or 'call-graph' (incremental)")
	flag.Parse()

	if *sourceDir == "" || *dbPath == "" {
		fmt.Fprintf(os.Stderr, "Usage: go-analyzer --source <path> --db <path> [--schema <path>] [--mode full|call-graph]\n")
		flag.PrintDefaults()
		os.Exit(1)
	}

	switch *mode {
	case "full":
		runFull(*sourceDir, *dbPath, *schemaPath)
	case "call-graph":
		runCallGraph(*sourceDir, *dbPath)
	default:
		log.Fatalf("Unknown mode %q: must be 'full' or 'call-graph'", *mode)
	}
}

func runFull(sourceDir, dbPath, schemaPath string) {
	if schemaPath == "" {
		log.Fatal("--schema is required for full mode")
	}

	// Open DB and apply schema
	db, err := OpenDB(dbPath, schemaPath)
	if err != nil {
		log.Fatalf("Failed to open database: %v", err)
	}
	defer db.Close()

	// Run analysis
	analyzer := NewAnalyzer(sourceDir)
	result, err := analyzer.Analyze()
	if err != nil {
		log.Fatalf("Analysis failed: %v", err)
	}

	// Resolve call graph before writing
	resolveCallGraph(result)

	// Write to DB
	writer := NewDBWriter(db)
	if err := writer.WriteAll(result); err != nil {
		log.Fatalf("Failed to write results: %v", err)
	}

	fmt.Printf("Analysis complete:\n")
	fmt.Printf("  Modules:       %d\n", len(result.Modules))
	fmt.Printf("  Features:      %d\n", result.TotalFeatures())
	fmt.Printf("  Unit Tests:    %d\n", result.TotalTests())
	fmt.Printf("  Dependencies:  %d\n", len(result.Dependencies))
	fmt.Printf("  Imports:       %d\n", len(result.Imports))
}

func runCallGraph(sourceDir, dbPath string) {
	// Open existing DB without schema
	db, err := OpenDBNoSchema(dbPath)
	if err != nil {
		log.Fatalf("Failed to open database: %v", err)
	}
	defer db.Close()

	// Run analysis (parse Go source)
	analyzer := NewAnalyzer(sourceDir)
	result, err := analyzer.Analyze()
	if err != nil {
		log.Fatalf("Analysis failed: %v", err)
	}

	// Resolve call graph
	resolveCallGraph(result)

	// Update DB incrementally
	writer := NewDBWriter(db)
	stats, err := writer.UpdateCallGraph(result)
	if err != nil {
		log.Fatalf("Failed to update call graph: %v", err)
	}

	fmt.Printf("Call graph analysis complete:\n")
	fmt.Printf("  Tests analyzed:    %d\n", stats.TestsAnalyzed)
	fmt.Printf("  Tests linked:      %d\n", stats.TestsLinked)
	fmt.Printf("  Dependency rows:   %d\n", stats.DependencyRows)
	fmt.Printf("  Feature IDs set:   %d\n", stats.FeatureIDsSet)
}
