package plugin

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"sync"

	"github.com/docker/cli/cli"
	"github.com/docker/cli/cli-plugins/metadata"
	"github.com/docker/cli/cli-plugins/socket"
	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/connhelper"
	"github.com/docker/cli/cli/debug"
	"github.com/moby/moby/client"
	"github.com/spf13/cobra"
	"go.opentelemetry.io/otel"
)

// PersistentPreRunE must be called by any plugin command (or
// subcommand) which uses the cobra `PersistentPreRun*` hook. Plugins
// which do not make use of `PersistentPreRun*` do not need to call
// this (although it remains safe to do so). Plugins are recommended
// to use `PersistentPreRunE` to enable the error to be
// returned. Should not be called outside of a command's
// PersistentPreRunE hook and must not be run unless Run has been
// called.
var PersistentPreRunE func(*cobra.Command, []string) error

// RunPlugin executes the specified plugin command
func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta metadata.Metadata) error {
	tcmd := newPluginCommand(dockerCli, plugin, meta)

	var persistentPreRunOnce sync.Once
	PersistentPreRunE = func(cmd *cobra.Command, _ []string) error {
		var retErr error
		persistentPreRunOnce.Do(func() {
			ctx, cancel := context.WithCancel(cmd.Context())
			cmd.SetContext(ctx)
			// Set up the context to cancel based on signalling via CLI socket.
			socket.ConnectAndWait(cancel)

			var opts []command.CLIOption
			if os.Getenv("DOCKER_CLI_PLUGIN_USE_DIAL_STDIO") != "" {
				opts = append(opts, withPluginClientConn(plugin.Name()))
			}
			opts = append(opts, command.WithEnableGlobalMeterProvider(), command.WithEnableGlobalTracerProvider())
			retErr = tcmd.Initialize(opts...)
			ogRunE := cmd.RunE
			if ogRunE == nil {
				ogRun := cmd.Run
				// necessary because error will always be nil here
				// see: https://github.com/golangci/golangci-lint/issues/1379
				//nolint:unparam
				ogRunE = func(cmd *cobra.Command, args []string) error {
					ogRun(cmd, args)
					return nil
				}
				cmd.Run = nil
			}
			cmd.RunE = func(cmd *cobra.Command, args []string) error {
				stopInstrumentation := dockerCli.StartInstrumentation(cmd)
				err := ogRunE(cmd, args)
				stopInstrumentation(err)
				return err
			}
		})
		return retErr
	}

	cmd, args, err := tcmd.HandleGlobalFlags()
	if err != nil {
		return err
	}
	// We've parsed global args already, so reset args to those
	// which remain.
	cmd.SetArgs(args)
	return cmd.Execute()
}

// Run is the top-level entry point to the CLI plugin framework. It should
// be called from the plugin's "main()" function. It initializes a new
// [command.DockerCli] instance with the given options before calling
// makeCmd to construct the plugin command, then invokes the plugin command
// using [RunPlugin].
func Run(makeCmd func(command.Cli) *cobra.Command, meta metadata.Metadata, ops ...command.CLIOption) {
	otel.SetErrorHandler(debug.OTELErrorHandler)

	dockerCLI, err := command.NewDockerCli(ops...)
	if err != nil {
		_, _ = fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	plugin := makeCmd(dockerCLI)

	if err := RunPlugin(dockerCLI, plugin, meta); err != nil {
		var stErr cli.StatusError
		if errors.As(err, &stErr) {
			// StatusError should only be used for errors, and all errors should
			// have a non-zero exit status, so never exit with 0
			if stErr.StatusCode == 0 { // FIXME(thaJeztah): this should never be used with a zero status-code. Check if we do this anywhere.
				stErr.StatusCode = 1
			}
			_, _ = fmt.Fprintln(dockerCLI.Err(), stErr)
			os.Exit(stErr.StatusCode)
		}
		_, _ = fmt.Fprintln(dockerCLI.Err(), err)
		os.Exit(1)
	}
}

func withPluginClientConn(name string) command.CLIOption {
	return func(cli *command.DockerCli) error {
		cmd := "docker"
		if x := os.Getenv(metadata.ReexecEnvvar); x != "" {
			cmd = x
		}
		var flags []string

		// Accumulate all the global arguments, that is those
		// up to (but not including) the plugin's name. This
		// ensures that `docker system dial-stdio` is
		// evaluating the same set of `--config`, `--tls*` etc
		// global options as the plugin was called with, which
		// in turn is the same as what the original docker
		// invocation was passed.
		for _, a := range os.Args[1:] {
			if a == name {
				break
			}
			flags = append(flags, a)
		}
		flags = append(flags, "system", "dial-stdio")

		helper, err := connhelper.GetCommandConnectionHelper(cmd, flags...)
		if err != nil {
			return err
		}
		apiClient, err := client.New(client.WithDialContext(helper.Dialer))
		if err != nil {
			return err
		}
		return command.WithAPIClient(apiClient)(cli)
	}
}

func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta metadata.Metadata) *cli.TopLevelCommand {
	name := plugin.Name()
	fullname := metadata.NamePrefix + name

	cmd := &cobra.Command{
		Use:           fmt.Sprintf("docker [OPTIONS] %s [ARG...]", name),
		Short:         fullname + " is a Docker CLI plugin",
		SilenceUsage:  true,
		SilenceErrors: true,
		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
			// We can't use this as the hook directly since it is initialised later (in runPlugin)
			return PersistentPreRunE(cmd, args)
		},
		TraverseChildren:      true,
		DisableFlagsInUseLine: true,
		CompletionOptions: cobra.CompletionOptions{
			DisableDefaultCmd:   false,
			HiddenDefaultCmd:    true,
			DisableDescriptions: os.Getenv("DOCKER_CLI_DISABLE_COMPLETION_DESCRIPTION") != "",
		},
	}

	// Disable file-completion by default. Most commands and flags should not
	// complete with filenames.
	cmd.CompletionOptions.SetDefaultShellCompDirective(cobra.ShellCompDirectiveNoFileComp)

	opts, _ := cli.SetupPluginRootCommand(cmd)

	cmd.SetIn(dockerCli.In())
	cmd.SetOut(dockerCli.Out())
	cmd.SetErr(dockerCli.Err())

	cmd.AddCommand(
		plugin,
		newMetadataSubcommand(plugin, meta),
	)

	visitAll(cmd,
		// prevent adding "[flags]" to the end of the usage line.
		func(c *cobra.Command) { c.DisableFlagsInUseLine = true },
	)

	return cli.NewTopLevelCommand(cmd, dockerCli, opts, cmd.Flags())
}

// visitAll traverses all commands from the root.
func visitAll(root *cobra.Command, fns ...func(*cobra.Command)) {
	for _, cmd := range root.Commands() {
		visitAll(cmd, fns...)
	}
	for _, fn := range fns {
		fn(root)
	}
}

func newMetadataSubcommand(plugin *cobra.Command, meta metadata.Metadata) *cobra.Command {
	if meta.ShortDescription == "" {
		meta.ShortDescription = plugin.Short
	}
	cmd := &cobra.Command{
		Use:    metadata.MetadataSubcommandName,
		Hidden: true,
		// Suppress the global/parent PersistentPreRunE, which
		// needlessly initializes the client and tries to
		// connect to the daemon.
		PersistentPreRun: func(cmd *cobra.Command, args []string) {},
		RunE: func(cmd *cobra.Command, args []string) error {
			enc := json.NewEncoder(os.Stdout)
			enc.SetEscapeHTML(false)
			enc.SetIndent("", "     ")
			return enc.Encode(meta)
		},
	}
	return cmd
}

// RunningStandalone tells a CLI plugin it is run standalone by direct execution
func RunningStandalone() bool {
	if os.Getenv(metadata.ReexecEnvvar) != "" {
		return false
	}
	return len(os.Args) < 2 || os.Args[1] != metadata.MetadataSubcommandName
}
