package main

import (
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

type CheckStatus int

const (
	StatusUnknown CheckStatus = iota
	StatusOK
	StatusFail
)

type CheckResult struct {
	Label  string
	Status CheckStatus
	Detail string
}

func RunChecks() []CheckResult {
	var results []CheckResult

	if path, err := exec.LookPath("nono"); err == nil {
		version := getNonoVersion()
		detail := path
		if version != "" {
			detail += " " + version
		}
		results = append(results, CheckResult{"nono installed", StatusOK, detail})
	} else {
		results = append(results, CheckResult{"nono installed", StatusFail, "not found in PATH"})
	}

	profilePath, _ := DefaultProfilePath()
	if profilePath != "" {
		if info, err := os.Stat(profilePath); err == nil {
			results = append(results, CheckResult{"profile installed", StatusOK,
				profilePath + " (" + info.ModTime().Format("2006-01-02") + ")"})
		} else {
			results = append(results, CheckResult{"profile installed", StatusFail, "not found"})
		}
	}

	home, _ := os.UserHomeDir()
	wrapperPath := filepath.Join(home, ".local", "bin", "opencode")
	if _, err := os.Stat(wrapperPath); err == nil {
		results = append(results, CheckResult{"wrapper installed", StatusOK, wrapperPath})
	} else {
		results = append(results, CheckResult{"wrapper installed", StatusFail, "not found"})
	}

	if path, err := exec.LookPath("opencode"); err == nil {
		if path == wrapperPath {
			results = append(results, CheckResult{"wrapper first on PATH", StatusOK, path})
		} else {
			results = append(results, CheckResult{"wrapper first on PATH", StatusFail, "resolves to " + path})
		}
	} else {
		results = append(results, CheckResult{"wrapper first on PATH", StatusFail, "opencode not in PATH"})
	}

	opencodePath := findRealOpencode(wrapperPath)
	if opencodePath != "" {
		results = append(results, CheckResult{"opencode binary", StatusOK, opencodePath})
	} else {
		results = append(results, CheckResult{"opencode binary", StatusFail, "real opencode not found"})
	}

	tinfoilDir := filepath.Join(home, ".tinfoil")
	if info, err := os.Stat(tinfoilDir); err == nil && info.IsDir() {
		results = append(results, CheckResult{"tinfoil credentials", StatusOK, tinfoilDir})
	} else {
		results = append(results, CheckResult{"tinfoil credentials", StatusFail, "no ~/.tinfoil directory"})
	}

	return results
}

func getNonoVersion() string {
	cmd := exec.Command("nono", "--version")
	out, err := cmd.Output()
	if err != nil {
		return ""
	}
	return strings.TrimSpace(string(out))
}

func findRealOpencode(wrapperPath string) string {
	path := os.Getenv("PATH")
	for _, dir := range filepath.SplitList(path) {
		for _, name := range []string{"opencode", "opencode.exe"} {
			candidate := filepath.Join(dir, name)
			if info, err := os.Stat(candidate); err == nil && !info.IsDir() {
				if candidate != wrapperPath {
					return candidate
				}
			}
		}
	}
	return ""
}
