package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/dokku/dokku/plugins/common"
	scheduler_k3s "github.com/dokku/dokku/plugins/scheduler-k3s"

	flag "github.com/spf13/pflag"
)

// main entrypoint to all subcommands
func main() {
	parts := strings.Split(os.Args[0], "/")
	subcommand := parts[len(parts)-1]

	var err error
	switch subcommand {
	case "annotations:set":
		args := flag.NewFlagSet("scheduler-k3s:annotations:set", flag.ExitOnError)
		global := args.Bool("global", false, "--global: set a global property")
		processType := args.String("process-type", "", "--process-type: scope to process-type")
		resourceType := args.String("resource-type", "", "--resource-type: scope to resource-type")
		args.Parse(os.Args[2:])
		appName := args.Arg(0)
		property := args.Arg(1)
		value := args.Arg(2)
		if *global {
			appName = "--global"
			property = args.Arg(0)
			value = args.Arg(1)
		}

		err = scheduler_k3s.CommandAnnotationsSet(appName, *processType, *resourceType, property, value)
	case "autoscaling-auth:set":
		args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:set", flag.ExitOnError)
		global := args.Bool("global", false, "--global: set a global property")
		metadata := args.StringToString("metadata", map[string]string{}, "--metadata: a key=value map of parameter metadata")
		args.Parse(os.Args[2:])
		appName := args.Arg(0)
		trigger := args.Arg(1)
		if *global {
			appName = "--global"
			trigger = args.Arg(0)
		}
		err = scheduler_k3s.CommandAutoscalingAuthSet(appName, trigger, *metadata, *global)
	case "autoscaling-auth:report":
		args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:report", flag.ExitOnError)
		global := args.Bool("global", false, "--global: show a global report")
		includeMetadata := args.Bool("include-metadata", false, "--include-metadata: include metadata in the report")
		format := args.String("format", "stdout", "format: [ stdout | json ]")
		args.Parse(os.Args[2:])
		appName := args.Arg(0)
		err = scheduler_k3s.CommandAutoscalingAuthReport(appName, *format, *global, *includeMetadata)
	case "cluster:add":
		args := flag.NewFlagSet("scheduler-k3s:cluster:add", flag.ExitOnError)
		allowUknownHosts := args.Bool("insecure-allow-unknown-hosts", false, "insecure-allow-unknown-hosts: allow unknown hosts")
		taintScheduling := args.Bool("taint-scheduling", false, "taint-scheduling: add a taint against scheduling app workloads")
		serverIP := args.String("server-ip", "", "server-ip: IP address of the dokku server node")
		kubeletArgs := args.StringSlice("kubelet-args", []string{}, "kubelet-args: repeatable key=value kubelet arguments (e.g., --kubelet-args key=value)")
		role := args.String("role", "worker", "role: [ server | worker ]")
		profileName := args.String("profile", "", "profile: name of the node profile to use")
		args.Parse(os.Args[2:])
		remoteHost := args.Arg(0)
		err = scheduler_k3s.CommandClusterAdd(*profileName, *role, remoteHost, *serverIP, *allowUknownHosts, *taintScheduling, *kubeletArgs)
	case "cluster:list":
		args := flag.NewFlagSet("scheduler-k3s:cluster:list", flag.ExitOnError)
		format := args.String("format", "stdout", "format: [ stdout | json ]")
		args.Parse(os.Args[2:])
		err = scheduler_k3s.CommandClusterList(*format)
	case "cluster:remove":
		args := flag.NewFlagSet("scheduler-k3s:cluster:remove", flag.ExitOnError)
		args.Parse(os.Args[2:])
		nodeName := args.Arg(0)
		err = scheduler_k3s.CommandClusterRemove(nodeName)
	case "ensure-charts":
		args := flag.NewFlagSet("scheduler-k3s:ensure-charts", flag.ExitOnError)
		forceInstall := args.Bool("force", false, "--force: force install all charts")
		chartNames := args.StringSlice("charts", []string{}, "--charts: comma separated list of chart names to force install")
		args.Parse(os.Args[2:])
		err = scheduler_k3s.CommandEnsureCharts(*forceInstall, *chartNames)
	case "initialize":
		args := flag.NewFlagSet("scheduler-k3s:initialize", flag.ExitOnError)
		taintScheduling := args.Bool("taint-scheduling", false, "taint-scheduling: add a taint against scheduling app workloads")
		serverIP := args.String("server-ip", "", "server-ip: IP address of the dokku server node")
		ingressClass := args.String("ingress-class", "nginx", "ingress-class: ingress-class to use for all outbound traffic")
		args.Parse(os.Args[2:])
		err = scheduler_k3s.CommandInitialize(*ingressClass, *serverIP, *taintScheduling)
	case "labels:set":
		args := flag.NewFlagSet("scheduler-k3s:labels:set", flag.ExitOnError)
		global := args.Bool("global", false, "--global: set a global property")
		processType := args.String("process-type", "", "--process-type: scope to process-type")
		resourceType := args.String("resource-type", "", "--resource-type: scope to resource-type")
		args.Parse(os.Args[2:])
		appName := args.Arg(0)
		property := args.Arg(1)
		value := args.Arg(2)
		if *global {
			appName = "--global"
			property = args.Arg(0)
			value = args.Arg(1)
		}

		err = scheduler_k3s.CommandLabelsSet(appName, *processType, *resourceType, property, value)
	case "profiles:add":
		args := flag.NewFlagSet("scheduler-k3s:profiles:add", flag.ExitOnError)
		role := args.String("role", "worker", "role: [ server | worker ]")
		allowUknownHosts := args.Bool("insecure-allow-unknown-hosts", false, "insecure-allow-unknown-hosts: allow unknown hosts")
		taintScheduling := args.Bool("taint-scheduling", false, "taint-scheduling: add a taint against scheduling app workloads")
		kubeletArgs := args.StringSlice("kubelet-args", []string{}, "kubelet-args: repeatable key=value kubelet arguments (e.g., --kubelet-args key=value)")
		args.Parse(os.Args[2:])
		profileName := args.Arg(0)
		err = scheduler_k3s.CommandProfilesAdd(profileName, *role, *allowUknownHosts, *taintScheduling, *kubeletArgs)
	case "profiles:list":
		args := flag.NewFlagSet("scheduler-k3s:profiles:list", flag.ExitOnError)
		format := args.String("format", "stdout", "format: [ stdout | json ]")
		args.Parse(os.Args[2:])
		err = scheduler_k3s.CommandProfilesList(*format)
	case "profiles:remove":
		args := flag.NewFlagSet("scheduler-k3s:profiles:remove", flag.ExitOnError)
		args.Parse(os.Args[2:])
		profileName := args.Arg(0)
		err = scheduler_k3s.CommandProfilesRemove(profileName)
	case "report":
		args := flag.NewFlagSet("scheduler-k3s:report", flag.ExitOnError)
		format := args.String("format", "stdout", "format: [ stdout | json ]")
		osArgs, infoFlag, flagErr := common.ParseReportArgs("scheduler-k3s", os.Args[2:])
		if flagErr == nil {
			args.Parse(osArgs)
			appName := args.Arg(0)
			err = scheduler_k3s.CommandReport(appName, *format, infoFlag)
		}
	case "set":
		args := flag.NewFlagSet("scheduler-k3s:set", flag.ExitOnError)
		global := args.Bool("global", false, "--global: set a global property")
		args.Parse(os.Args[2:])
		appName := args.Arg(0)
		property := args.Arg(1)
		value := args.Arg(2)
		if *global {
			appName = "--global"
			property = args.Arg(0)
			value = args.Arg(1)
		}
		err = scheduler_k3s.CommandSet(appName, property, value)
	case "show-kubeconfig":
		args := flag.NewFlagSet("scheduler-k3s:show-kubeconfig", flag.ExitOnError)
		args.Parse(os.Args[2:])
		err = scheduler_k3s.CommandShowKubeconfig()
	case "uninstall":
		args := flag.NewFlagSet("scheduler-k3s:uninstall", flag.ExitOnError)
		args.Parse(os.Args[2:])
		err = scheduler_k3s.CommandUninstall()
	default:
		err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
	}

	if err != nil {
		common.LogFailWithError(err)
	}
}
