package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"text/tabwriter"
)

func cmdAnalysis(args []string) {
	if len(args) < 1 {
		printAnalysisUsage()
		os.Exit(1)
	}

	switch args[0] {
	case "list":
		analysisList()
	case "clone":
		if len(args) < 2 {
			fmt.Fprintln(os.Stderr, "usage: fn analysis clone <id>")
			os.Exit(1)
		}
		analysisClone(args[1])
	case "pull":
		if len(args) < 2 {
			fmt.Fprintln(os.Stderr, "usage: fn analysis pull <id>")
			os.Exit(1)
		}
		analysisPull(args[1])
	case "help", "-h":
		printAnalysisUsage()
	default:
		fmt.Fprintf(os.Stderr, "unknown analysis command: %s\n", args[0])
		printAnalysisUsage()
		os.Exit(1)
	}
}

func printAnalysisUsage() {
	fmt.Println(`fn analysis — manage registry analyses

Usage:
  fn analysis list              List all analyses (local + remote)
  fn analysis clone <id>        Clone analysis repo to analysis/<name>/
  fn analysis pull <id>         Git pull in existing clone`)
}

func analysisList() {
	db := openDB()
	defer db.Close()

	items, err := db.ListAllAnalysis()
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}

	if len(items) == 0 {
		fmt.Println("No analyses registered.")
		return
	}

	r := root()
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
	fmt.Fprintln(w, "ID\tLANG\tDOMAIN\tSTATUS\tREPO_URL")
	for _, a := range items {
		status := "local"
		if a.RepoURL != "" {
			dirPath := filepath.Join(r, "analysis", a.Name)
			if _, err := os.Stat(dirPath); os.IsNotExist(err) {
				status = "remote"
			} else {
				status = "cloned"
			}
		}
		fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", a.ID, a.Lang, a.Domain, status, a.RepoURL)
	}
	w.Flush()
}

func analysisClone(id string) {
	db := openDB()
	defer db.Close()

	a, err := db.GetAnalysis(id)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}

	if a.RepoURL == "" {
		fmt.Fprintf(os.Stderr, "analysis %s has no repo_url set\n", id)
		os.Exit(1)
	}

	r := root()
	target := filepath.Join(r, "analysis", a.Name)
	if _, err := os.Stat(target); err == nil {
		fmt.Fprintf(os.Stderr, "directory already exists: %s\n", target)
		os.Exit(1)
	}

	fmt.Printf("Cloning %s → %s\n", a.RepoURL, target)
	cmd := exec.Command("git", "clone", a.RepoURL, target)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		fmt.Fprintf(os.Stderr, "git clone failed: %v\n", err)
		os.Exit(1)
	}
	fmt.Println("Done. Run 'fn index' to re-index.")
}

func analysisPull(id string) {
	db := openDB()
	defer db.Close()

	a, err := db.GetAnalysis(id)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}

	r := root()
	dir := filepath.Join(r, "analysis", a.Name)
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		fmt.Fprintf(os.Stderr, "analysis not cloned locally: %s\n", dir)
		fmt.Fprintln(os.Stderr, "Run 'fn analysis clone "+id+"' first.")
		os.Exit(1)
	}

	fmt.Printf("Pulling %s\n", dir)
	cmd := exec.Command("git", "-C", dir, "pull")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		fmt.Fprintf(os.Stderr, "git pull failed: %v\n", err)
		os.Exit(1)
	}
	fmt.Println("Done. Run 'fn index' to re-index.")
}
