package cmd

import (
	"slices"

	"git.secluded.site/keld/internal/ui/screens"
)

// wrappedCommand describes a restic command that keld exposes in its
// interactive menu and shell completions.
type wrappedCommand struct {
	Name   string
	Hotkey rune
}

// wrappedCommands lists the restic commands keld actively wraps. Adding
// an entry here automatically surfaces it in the TUI menu and shell
// completions. The order determines menu display order.
var wrappedCommands = []wrappedCommand{
	{Name: "backup", Hotkey: 'b'},
	{Name: "restore", Hotkey: 'r'},
	{Name: "snapshots", Hotkey: 's'},
	{Name: "forget", Hotkey: 'f'},
	{Name: "check", Hotkey: 'c'},
	{Name: "init", Hotkey: 'i'},
}

// menuItems is derived from wrappedCommands for the interactive menu.
var menuItems = func() []screens.MenuItem {
	items := make([]screens.MenuItem, len(wrappedCommands))
	for i, wc := range wrappedCommands {
		items[i] = screens.MenuItem{Label: wc.Name, Hotkey: wc.Hotkey}
	}
	return items
}()

// knownCommands is derived from wrappedCommands for shell completion.
var knownCommands = func() []string {
	names := make([]string, len(wrappedCommands))
	for i, wc := range wrappedCommands {
		names[i] = wc.Name
	}
	return names
}()

// isWrappedCommand reports whether the given command name is one of
// the commands keld actively wraps with TUI screens.
func isWrappedCommand(name string) bool {
	return slices.Contains(knownCommands, name)
}

// flagContract describes a restic flag that keld semantically depends on
// (e.g. used in HasFlag checks or keyAliases).
type flagContract struct {
	Command    string
	Name       string
	IsBool     bool
	Repeatable bool
}

// flagContracts lists flags keld's wrapper logic hardcodes assumptions
// about. Contract tests verify these still match the generated data.
var flagContracts = []flagContract{
	{Command: "restore", Name: "target", IsBool: false, Repeatable: false},
	{Command: "global", Name: "repo", IsBool: false, Repeatable: false},
}

// passthroughCommands lists restic commands that keld does not actively wrap
// but should still allow through without error. Contract tests verify that
// every command in restic.Commands is either wrapped or listed here.
var passthroughCommands = map[string]struct{}{
	"cache":            {},
	"cat":              {},
	"copy":             {},
	"diff":             {},
	"dump":             {},
	"features":         {},
	"find":             {},
	"generate":         {},
	"key":              {},
	"key-add":          {},
	"key-list":         {},
	"key-passwd":       {},
	"key-remove":       {},
	"list":             {},
	"ls":               {},
	"migrate":          {},
	"mount":            {},
	"options":          {},
	"prune":            {},
	"recover":          {},
	"repair":           {},
	"repair-index":     {},
	"repair-packs":     {},
	"repair-snapshots": {},
	"rewrite":          {},
	"stats":            {},
	"tag":              {},
	"unlock":           {},
	"version":          {},
}
