package cli

import (
	cli "github.com/lxc/incus/v7/shared/cmd"
	"github.com/spf13/cobra"
)

// IncusOS application command.
type cmdAdminOSApplication struct {
	os *cmdAdminOS
}

func (c *cmdAdminOSApplication) command() *cobra.Command {
	cmd := &cobra.Command{}
	cmd.Use = cli.Usage("application")
	cmd.Short = "Manage IncusOS applications"
	cmd.Long = cli.FormatSection("Description", "Manage IncusOS applications")

	// Action.
	actionCmd := cmdGenericRun{
		os:          c.os,
		action:      "action",
		description: "Perform application-specific action",
		endpoint:    "applications",
		entity:      "application",
		hasData:     true,
		defaultData: "{}",
	}
	cmd.AddCommand(actionCmd.command())

	// Add.
	addCmd := cmdGenericRun{
		os:          c.os,
		name:        "add",
		description: "Add an application",
		endpoint:    "applications",
		dataArgs:    []string{"application"},
		dataFunc: func(args []string) (any, error) {
			return map[string]string{"name": args[0]}, nil
		},
	}
	cmd.AddCommand(addCmd.command())

	// Backup.
	backupCmd := cmdGenericRun{
		os:            c.os,
		action:        "backup",
		description:   "Backup the application",
		endpoint:      "applications",
		entity:        "application",
		hasData:       true,
		defaultData:   "{}",
		hasFileOutput: true,
	}
	cmd.AddCommand(backupCmd.command())

	// Check update.
	checkUpdateCmd := cmdGenericRun{
		os:          c.os,
		action:      "check-update",
		description: "Check for application update",
		endpoint:    "applications",
		entity:      "application",
	}
	cmd.AddCommand(checkUpdateCmd.command())

	// Debug.
	debugCmd := cmdGenericRun{
		os:          c.os,
		action:      "debug",
		description: "Debug the application",
		endpoint:    "applications",
		entity:      "application",
		hasData:     true,
		defaultData: "{}",
	}
	cmd.AddCommand(debugCmd.command())

	// Edit.
	editCmd := cmdGenericEdit{os: c.os, entity: "application", entityShort: "application", endpoint: "applications"}
	cmd.AddCommand(editCmd.command())

	// Factory reset.
	factoryResetCmd := cmdGenericRun{
		os:          c.os,
		action:      "factory-reset",
		description: "Factory reset the application",
		endpoint:    "applications",
		entity:      "application",
		hasData:     true,
		defaultData: "{}",
		confirm:     "factory-reset the application",
	}
	cmd.AddCommand(factoryResetCmd.command())

	// List.
	listCmd := cmdGenericList{os: c.os, entity: "applications", endpoint: "applications"}
	cmd.AddCommand(listCmd.command())

	// Remove.
	removeCmd := cmdGenericRun{
		os:          c.os,
		action:      "remove",
		description: "Remove the application",
		endpoint:    "applications",
		entity:      "application",
		confirm:     "remove the application",
	}
	cmd.AddCommand(removeCmd.command())

	// Restart.
	restartCmd := cmdGenericRun{
		os:          c.os,
		action:      "restart",
		description: "Restart the application",
		endpoint:    "applications",
		entity:      "application",
		confirm:     "restart the application",
	}
	cmd.AddCommand(restartCmd.command())

	// Restore.
	restoreCmd := cmdGenericRun{
		os:           c.os,
		action:       "restore",
		description:  "Restore an application backup",
		endpoint:     "applications",
		entity:       "application",
		hasFileInput: true,
		confirm:      "restore the system state to provided backup",
	}
	cmd.AddCommand(restoreCmd.command())

	// Switch version.
	switchVersionCmd := cmdGenericRun{
		os:          c.os,
		action:      "switch-version",
		description: "Change application version",
		endpoint:    "applications",
		entity:      "application",
		hasData:     true,
		defaultData: "{}",
		confirm:     "change the running version of the application",
	}
	cmd.AddCommand(switchVersionCmd.command())

	// Show.
	showCmd := cmdGenericShow{os: c.os, entity: "application", entityShort: "application", endpoint: "applications"}
	cmd.AddCommand(showCmd.command())

	// Workaround for subcommand usage errors. See: https://github.com/spf13/cobra/issues/706.
	cmd.Args = cobra.NoArgs
	cmd.Run = func(cmd *cobra.Command, _ []string) { _ = cmd.Usage() }

	return cmd
}
