package cmd

import (
	"fmt"

	"nest/src/detect"
	"nest/src/output"
)

const listUsage = `Usage: nest list [--all | --installed | --available] [--json] [--catalog path]

List cataloged tools. Default is --all in host mode, --installed inside a
container. STATUS and CONTAINER columns are always shown: a tool is runnable
when installed locally, or when a container is available for it.
`

func (a *App) cmdList(args []string) int {
	fs := a.newFlagSet("list", listUsage)
	all := fs.Bool("all", false, "show all tools, with a status column")
	installed := fs.Bool("installed", false, "show only tools detected on this system")
	available := fs.Bool("available", false, "show only tools not installed locally")
	jsonOut := fs.Bool("json", false, "JSON output (stable schema, see AGENTS.md §4.8)")
	catalogFlag := fs.String("catalog", "", "use the catalog at path (development/testing)")
	positionals, ok, code := a.parseInterspersed(fs, args)
	if !ok {
		return code
	}
	if len(positionals) > 0 {
		fmt.Fprintf(a.Stderr, "nest: list takes no arguments\n")
		return exitUsage
	}
	selected := 0
	for _, b := range []bool{*all, *installed, *available} {
		if b {
			selected++
		}
	}
	if selected > 1 {
		fmt.Fprintf(a.Stderr, "nest: --all, --installed and --available are mutually exclusive\n")
		return exitUsage
	}

	cat, _, code := a.loadCatalog(*catalogFlag)
	if code != exitOK {
		return code
	}

	// §4.1: --installed is the default in container mode, --all in host mode.
	wantInstalled, wantAvailable := *installed, *available
	if !*all && !*installed && !*available && detect.InContainer(a.Getenv) {
		wantInstalled = true
	}

	summaries := make([]output.ToolSummary, 0, len(cat.Tools))
	var rows [][]string
	for i := range cat.Tools {
		tool := &cat.Tools[i]
		s := output.Summarize(tool)
		if wantInstalled && !s.Installed {
			continue
		}
		// §4.1: --available means not installed AND a container is available.
		if wantAvailable && (s.Installed || !tool.HasImage()) {
			continue
		}
		summaries = append(summaries, s)
		rows = append(rows, []string{s.Name, statusWord(s.Installed), containerWord(tool.HasImage()), s.Package, s.Description})
	}

	if *jsonOut {
		if err := output.JSON(a.Stdout, summaries); err != nil {
			fmt.Fprintf(a.Stderr, "nest: cannot render JSON: %v\n", err)
			return exitError
		}
		return exitOK
	}
	header := []string{"NAME", "STATUS", "CONTAINER", "PACKAGE", "DESCRIPTION"}
	if err := output.Table(a.Stdout, header, rows); err != nil {
		fmt.Fprintf(a.Stderr, "nest: cannot render table: %v\n", err)
		return exitError
	}
	return exitOK
}

func statusWord(installed bool) string {
	if installed {
		return "installed"
	}
	return "not installed"
}

func containerWord(hasImage bool) string {
	if hasImage {
		return "yes"
	}
	return "no"
}
