package edgecmd

import "github.com/spf13/cobra"

// Options provides command roots owned by the edge main package while keeping
// command support logic inside the edgecmd package.
type Options struct {
	ConfigPath *string
	Serve      *cobra.Command
	Console    *cobra.Command
}

// NewRoot builds the iop-edge command surface.
func NewRoot(opts Options) *cobra.Command {
	configPath := opts.ConfigPath
	if configPath == nil {
		var localConfigPath string
		configPath = &localConfigPath
	}

	root := &cobra.Command{
		Use:   "edge",
		Short: "IOP Edge — execution group controller",
		Long: `IOP Edge is the backend execution group controller that coordinates multiple execution nodes.
It manages token-based node registration, node registry, node configuration delivery, and OpenAI-compatible routing.

The official local development and field test flow is as follows:
  1. config init    - Write a clean local edge.yaml configuration template.
  2. env            - Verify resolved local environment, log paths, and listen URLs.
  3. node register  - Add a node record to edge.yaml and generate its one-line bootstrap command.
  4. config check   - Validate the edge.yaml configuration structure and constraints.
  5. serve (or console) - Start the Edge server (or interactive console) to accept connections.
  6. nodes list     - List configured nodes and show their connection status.
  7. smoke openai   - Perform an E2E health, models, and responses smoke test on the OpenAI endpoint.`,
		Example: `  iop-edge config init
  iop-edge env
  iop-edge node register my-node --adapter ollama
  iop-edge config check
  iop-edge serve
  iop-edge nodes list
  iop-edge smoke openai --model gemma4:26b`,
	}
	root.PersistentFlags().StringVarP(configPath, "config", "c", "", "config file path (defaults to bundle-local edge.yaml)")

	commands := make([]*cobra.Command, 0, 10)
	if opts.Serve != nil {
		commands = append(commands, opts.Serve)
	}
	if opts.Console != nil {
		commands = append(commands, opts.Console)
	}
	commands = append(commands, versionCmd(), configCmd(), envCmd(), setupCmd(), bootstrapCmd(), nodeCmd(), nodesCmd(), smokeCmd())
	root.AddCommand(commands...)
	return root
}
