package common

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"os"
	"runtime"
	"sort"

	"cloud.google.com/go/logging"
	"go.skia.org/infra/go/cleanup"
	"go.skia.org/infra/go/metrics2"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/sklog/cloudlogging"
	"go.skia.org/infra/go/sklog/sklogimpl"
	"golang.org/x/oauth2/google"
)

// FlagSet is the flag.FlagSet we use to parse command line flags.
// It defaults to flag.CommandLine, but can be over-ridden with
// FlagSetOpt.
var FlagSet *flag.FlagSet = flag.CommandLine

// Opt represents the initialization parameters for a single init service, where
// services are Prometheus, etc.
//
// Initializing flags, metrics, and logging, with two options for metrics, and
// another option for logging is complicated by the fact that some
// initializations are order dependent, and each app may want a different
// subset of options. The solution is to encapsulate each optional piece,
// prom, etc, into its own Opt, and then initialize each Opt in the
// right order.
//
// Not only are the Opts order dependent but initialization needs to be broken
// into two phases, preinit() and init().
//
// The desired order for all Opts is:
//
//	0 - base
//	1 - cloudlogging
//	3 - prometheus
//	4 - slog
//
// Construct the Opts that are desired and pass them to common.InitWith(), i.e.:
//
//	common.InitWith(
//		"skiaperf",
//		common.PrometheusOpt(promPort),
//		common.CloudLoggingOpt(),
//	)
type Opt interface {
	// order is the sort order that Opts are executed in.
	order() int
	preinit(appName string) error
	init(appName string) error
}

// optSlice is a utility type for sorting Opts by order().
type optSlice []Opt

func (p optSlice) Len() int           { return len(p) }
func (p optSlice) Less(i, j int) bool { return p[i].order() < p[j].order() }
func (p optSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

// baseInitOpt is an Opt that is always constructed internally, added to any
// Opts passed into InitWith() and always runs first.
//
// Implements Opt.
type baseInitOpt struct{}

func (b *baseInitOpt) preinit(appName string) error {
	return FlagSet.Parse(os.Args[1:])
}

func (b *baseInitOpt) init(appName string) error {
	// Log all flags and their values.
	FlagSet.VisitAll(func(f *flag.Flag) {
		sklog.Infof("Flags: --%s=%v", f.Name, f.Value)
	})

	// Log all environment variables.
	for _, env := range os.Environ() {
		sklog.Infof("Env: %s", env)
	}

	// Use all cores.
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Enable signal handling for the cleanup package.
	cleanup.Enable()

	// Record UID and GID.
	sklog.Infof("Running as %d:%d", os.Getuid(), os.Getgid())

	return nil
}

func (b *baseInitOpt) order() int {
	return 0
}

// cloudLoggingInitOpt implements Opt for cloud logging.
type cloudLoggingInitOpt struct {
	projectID string
	local     *bool
}

// CloudLogging creates an Opt to initialize cloud logging when passed to InitWith().
//
// Uses the instance service account for auth.
// No cloud logging is done if local is true.
func CloudLogging(local *bool, projectID string) Opt {
	return &cloudLoggingInitOpt{
		projectID: projectID,
		local:     local,
	}
}

func (o *cloudLoggingInitOpt) preinit(appName string) error {
	ctx := context.Background()
	if *o.local {
		return nil
	}
	ts, err := google.DefaultTokenSource(ctx, logging.WriteScope)
	if err != nil {
		return fmt.Errorf("problem getting authenticated token source: %s", err)
	}
	// Try to grab a token right away to confirm auth is set up correctly.
	_, err = ts.Token()
	if err != nil {
		return err
	}
	hostname, err := os.Hostname()
	if err != nil {
		return err
	}
	l, err := cloudlogging.New(ctx, o.projectID, appName, ts, map[string]string{"hostname": hostname})
	if err != nil {
		return err
	}
	sklogimpl.SetLogger(l)
	return nil
}

func (o *cloudLoggingInitOpt) init(appName string) error {
	return nil
}

func (o *cloudLoggingInitOpt) order() int {
	return 1
}

// metricsLoggingInitOpt implements Opt for logging with metrics.
type metricsLoggingInitOpt struct {
}

func (o *metricsLoggingInitOpt) preinit(appName string) error {
	return nil
}

func (o *metricsLoggingInitOpt) init(appName string) error {
	severities := sklogimpl.AllSeverities()
	metricLookup := make([]metrics2.Counter, len(severities))
	for _, sev := range severities {
		metricLookup[sev] = metrics2.GetCounter("num_log_lines", map[string]string{"level": sev.String()})
	}
	metricsCallback := func(severity sklogimpl.Severity) {
		metricLookup[severity].Inc(1)
	}
	sklogimpl.SetMetricsCallback(metricsCallback)
	return nil
}

func (o *metricsLoggingInitOpt) order() int {
	return 2
}

// promInitOpt implments Opt for Prometheus.
type promInitOpt struct {
	port *string
}

// PrometheusOpt creates an Opt to initialize Prometheus metrics when passed to InitWith().
func PrometheusOpt(port *string) Opt {
	return &promInitOpt{
		port: port,
	}
}

func (o *promInitOpt) preinit(appName string) error {
	metrics2.InitPrometheus(*o.port)
	return nil
}

var defaultServeMux http.ServeMux

func (o *promInitOpt) init(appName string) error {
	// App uptime.
	_ = metrics2.NewLiveness("uptime", nil)

	// Prometheus client loads "expvar" which automatically registers
	// "/debug/vars" in the default http handler, which exposes potentially
	// secret information. Since we can't register a new handler for
	// "/debug/vars" because that causes the http lib to panic, we need to
	// replace http.DefaultServeMux with a fresh handler, and since we do this
	// after init()'s have been called, we won't get the /debug/vars handler.
	// http://b/241539244
	http.DefaultServeMux = &defaultServeMux
	http.HandleFunc("/debug/vars", http.NotFound)
	return nil
}

func (o *promInitOpt) order() int {
	return 3
}

// flagSetInitOpt implments Opt for flag.FlagSet.
type flagSetInitOpt struct {
	flagSet *flag.FlagSet
}

// FlagSetOpt allows changing the flag.FlagSet used to parse command line arguments.
//
// If this Opt is not used then flag.CommandLine is used as the default.
func FlagSetOpt(flagSet *flag.FlagSet) Opt {
	return &flagSetInitOpt{
		flagSet: flagSet,
	}
}

func (o *flagSetInitOpt) preinit(appName string) error {
	FlagSet = o.flagSet
	return nil
}

func (o *flagSetInitOpt) init(appName string) error {
	return nil
}

func (o *flagSetInitOpt) order() int {
	return -1
}

// InitWith takes Opt's and initializes each service, where services are Prometheus, etc.
func InitWith(appName string, opts ...Opt) error {

	// Add baseInitOpt and metricsLoggingInitOpt.
	opts = append(opts, &baseInitOpt{}, &metricsLoggingInitOpt{})

	// Sort by order().
	sort.Sort(optSlice(opts))

	// Check for duplicate Opts.
	for i := 0; i < len(opts)-1; i++ {
		if opts[i].order() == opts[i+1].order() {
			return fmt.Errorf("only one of each type of Opt can be used")
		}
	}

	// Run all preinit's.
	for _, o := range opts {
		if err := o.preinit(appName); err != nil {
			return err
		}
	}

	// Run all init's.
	for _, o := range opts {
		if err := o.init(appName); err != nil {
			return err
		}
	}
	sklog.Flush()
	return nil
}

// InitWithMust calls InitWith and fails fatally if an error is encountered.
func InitWithMust(appName string, opts ...Opt) {
	if err := InitWith(appName, opts...); err != nil {
		sklog.Fatalf("Failed to initialize: %s", err)
	}
}
