package options

import (
	"fmt"
	"os"

	"github.com/spf13/pflag"
	"k8s.io/client-go/tools/clientcmd"

	"github.com/tidbcloud/shared-provider/cmd/throttler/app/config"
)

// Options is flags of manager.
type Options struct {
	Kubeconfig string

	// TODO: extract common options
	MetricsBindAddress     string
	WebhookPort            int
	HealthProbeBindAddress string

	NodeName string
}

// New returns default running options
// nolint: gomnd // all constants are default config
func New() *Options {
	opt := &Options{
		Kubeconfig:             "",
		MetricsBindAddress:     ":8080",
		WebhookPort:            9443,
		HealthProbeBindAddress: ":8081",
		NodeName:               os.Getenv("NODE_NAME"),
	}

	return opt
}

// AddFlags adds flags for manager.
func (opt *Options) AddFlags(fs *pflag.FlagSet) {
	fs.StringVar(&opt.Kubeconfig, "kubeconfig", opt.Kubeconfig,
		"kubeconfig for user cluster",
	)

	fs.StringVar(&opt.MetricsBindAddress, "metrics-bind-address", opt.MetricsBindAddress,
		"The address the metric endpoint binds to.",
	)
	fs.StringVar(&opt.HealthProbeBindAddress, "health-probe-bind-address", opt.HealthProbeBindAddress,
		"The address the probe endpoint binds to.",
	)
	fs.IntVar(&opt.WebhookPort, "webhook-port", opt.WebhookPort,
		"The port of manager webhook.",
	)

	fs.StringVar(&opt.NodeName, "node-name", opt.NodeName,
		"The name of kubernetes node where throttled pods run.",
	)
}

// Config returns config of manager
// Validation of options can be done in here.
func (opt *Options) Config() (*config.Config, error) {
	kubeconfig, err := clientcmd.BuildConfigFromFlags("", opt.Kubeconfig)
	if err != nil {
		return nil, fmt.Errorf("can't parse kubeconfig: %w", err)
	}

	return &config.Config{
		Kubeconfig: kubeconfig,

		MetricsBindAddress:     opt.MetricsBindAddress,
		WebhookPort:            opt.WebhookPort,
		HealthProbeBindAddress: opt.HealthProbeBindAddress,

		NodeName: opt.NodeName,
	}, nil
}
