// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//  1. Redistributions of source code must retain the above copyright notice, this
//     list of conditions and the following disclaimer.
//
//  2. Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//  3. Neither the name of the copyright holder nor the names of its
//     contributors may be used to endorse or promote products derived from
//     this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Package subcmd provides a multi-command interface for command line tools.
package subcmd

import (
	"context"
	"errors"
	"flag"
	"fmt"
	"net/http"
	"net/http/pprof"
	"os"
	"path/filepath"
	"strings"
	"text/tabwriter"
)

// ErrInvalidCLA is the error returned when an invalid command line argument was
// provided, and the usage was already printed.
var ErrInvalidCLA = errors.New("invalid command line args")

// InvalidCLA shows the flag usage, and returns ErrInvalidCLA
func InvalidCLA() error {
	flag.Usage()
	return ErrInvalidCLA
}

// Command is the interface for a command
// Data is a generic data type passed down to the sub-command when run.
type Command[Data any] interface {
	// Name returns the name of the command.
	Name() string
	// Desc returns a description of the command.
	Desc() string
	// RegisterFlags registers all the command-specific flags
	// Returns a list of mandatory arguments that must immediately follow the
	// command name
	RegisterFlags(context.Context, Data) ([]string, error)
	// Run invokes the command
	Run(context.Context, Data) error
}

// DefaultCommand is the interface for a command that should be used as the
// default if no command is specified on the command line. Only one command can
// be the default command.
type DefaultCommand interface {
	IsDefaultCommand()
}

// Run handles the parses the command line arguments, possibly invoking one of
// the provided commands.
// If the command line arguments are invalid, then an error message is printed
// and Run returns ErrInvalidCLA.
func Run[Data any](ctx context.Context, data Data, cmds ...Command[Data]) error {
	_, exe := filepath.Split(os.Args[0])

	flag.Usage = func() {
		out := flag.CommandLine.Output()
		tw := tabwriter.NewWriter(out, 0, 1, 0, ' ', 0)
		fmt.Fprintln(tw, exe, "[command]")
		fmt.Fprintln(tw)
		fmt.Fprintln(tw, "Commands:")
		for _, cmd := range cmds {
			name := cmd.Name()
			_, isDefault := cmd.(DefaultCommand)
			if isDefault {
				name += " (default)"
			}
			fmt.Fprintln(tw, "  ", name, "\t-", strings.Split(cmd.Desc(), "\n")[0])
		}
		fmt.Fprintln(tw)
		fmt.Fprintln(tw, "Common flags:")
		tw.Flush()
		flag.PrintDefaults()
	}

	profile := false
	flag.BoolVar(&profile, "profile", false, "enable a webserver at localhost:8080/profile that exposes a CPU profiler")
	mux := http.NewServeMux()
	mux.HandleFunc("/profile", pprof.Profile)

	// Look for a default command
	var defaultCmd Command[Data]
	for _, cmd := range cmds {
		_, isDefault := cmd.(DefaultCommand)
		if isDefault {
			if defaultCmd != nil {
				panic(fmt.Sprintf("both commands %v and %v implement DefaultCommand", defaultCmd.Name(), cmd.Name()))
			}
			defaultCmd = cmd
		}
	}

	var cmdName string
	if len(os.Args) > 1 {
		cmdName = os.Args[1]
	}

	args := os.Args[1:] // Skip executable name

	// Find the requested command
	cmd := findCmd(cmdName, cmds)
	if cmd != nil {
		args = args[1:] // Skip command name
	}

	help := strings.TrimLeft(cmdName, "-") == "help"
	if help {
		if len(args) > 1 { // help cmd ...
			cmdName = args[1]
			cmd = findCmd(cmdName, cmds)
		}
		if cmd == nil {
			flag.Usage()
			return nil
		}
	}

	if cmd == nil { // Command not found
		if defaultCmd == nil {
			return InvalidCLA() // No default
		}
		cmd = defaultCmd // Use default command
	}

	out := flag.CommandLine.Output()
	mandatory, err := cmd.RegisterFlags(ctx, data)
	if err != nil {
		return err
	}
	flag.Usage = func() {
		flagsAndArgs := append([]string{"<flags>"}, mandatory...)
		fmt.Fprintln(out, exe, cmd.Name(), strings.Join(flagsAndArgs, " "))
		fmt.Fprintln(out)
		fmt.Fprintln(out, cmd.Desc())
		fmt.Fprintln(out)
		fmt.Fprintln(out, "flags:")
		flag.PrintDefaults()
	}
	if help {
		flag.Usage()
		return nil
	}
	if err := flag.CommandLine.Parse(args); err != nil {
		return err
	}
	if nonFlagArgs := flag.Args(); len(nonFlagArgs) < len(mandatory) {
		fmt.Fprintln(out, "missing argument", mandatory[len(nonFlagArgs)])
		fmt.Fprintln(out)
		return InvalidCLA()
	}
	if profile {
		fmt.Println("download profile at: localhost:8080/profile")
		fmt.Println("then run: 'go tool pprof <file>'")
		go http.ListenAndServe(":8080", mux)
	}

	return cmd.Run(ctx, data)
}

func findCmd[Data any](name string, cmds []Command[Data]) Command[Data] {
	for _, c := range cmds {
		if c.Name() == name {
			return c
		}
	}
	return nil
}
