// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package cmdconfig contains functions for configuring commands.
package cmdconfig

import (
	"context"
	"fmt"
	"net/http"
	"strings"
	"time"

	"cloud.google.com/go/errorreporting"
	"cloud.google.com/go/logging"
	"contrib.go.opencensus.io/integrations/ocsql"
	_ "github.com/jackc/pgx/v5/stdlib" // for pgx driver
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/config"
	"golang.org/x/pkgsite/internal/config/dynconfig"
	"golang.org/x/pkgsite/internal/config/serverconfig"
	"golang.org/x/pkgsite/internal/database"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/log"
	"golang.org/x/pkgsite/internal/log/stackdriverlogger"
	"golang.org/x/pkgsite/internal/middleware"
	"golang.org/x/pkgsite/internal/postgres"
	mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
)

// Logger configures a middleware.Logger.
func Logger(ctx context.Context, cfg *config.Config, logName string) middleware.Logger {
	if serverconfig.OnGCP() {
		opts := []logging.LoggerOption{logging.CommonResource(&mrpb.MonitoredResource{
			Type:   cfg.MonitoredResource.Type,
			Labels: cfg.MonitoredResource.Labels,
		})}
		if serverconfig.OnCloudRun() {
			opts = append(opts, logging.CommonLabels(map[string]string{
				// Standard label for Cloud Run instance ID.
				// See https://cloud.google.com/run/docs/logging#service-fields.
				"instanceId": cfg.InstanceID,
			}))
		}
		if serverconfig.OnGKE() {
			opts = append(opts, logging.CommonLabels(map[string]string{
				"k8s-pod/env": cfg.DeploymentEnvironment(),
				"k8s-pod/app": cfg.Application(),
			}))
		}
		logger, parent, err := stackdriverlogger.New(ctx, logName, cfg.ProjectID, opts)
		log.Use(logger)
		if err != nil {
			log.Fatal(ctx, err)
		}
		return parent
	}
	return middleware.LocalLogger{}
}

// Reporter configures an Error Reporting client.
func Reporter(ctx context.Context, cfg *config.Config) derrors.Reporter {
	if !serverconfig.OnGCP() || cfg.DisableErrorReporting {
		return nil
	}
	reportingClient, err := errorreporting.NewClient(ctx, cfg.ProjectID, errorreporting.Config{
		ServiceName: cfg.ServiceID,
		OnError: func(err error) {
			log.Errorf(ctx, "Error reporting failed: %v", err)
		},
	})
	if err != nil {
		log.Fatal(ctx, err)
	}
	reporter := &reporter{reportingClient}
	derrors.SetReporter(reporter)
	return reporter
}

type reporter struct {
	c *errorreporting.Client
}

func (r *reporter) Report(err error, req *http.Request, stack []byte) {
	r.c.Report(errorreporting.Entry{Error: err, Req: req, Stack: stack})
}

// Experimenter configures a middleware.Experimenter.
func Experimenter(ctx context.Context, cfg *config.Config, getter middleware.ExperimentGetter, reporter derrors.Reporter) *middleware.Experimenter {
	e, err := middleware.NewExperimenter(ctx, 1*time.Minute, getter, reporter)
	if err != nil {
		log.Fatal(ctx, err)
	}
	return e
}

// ExperimentGetter returns an ExperimentGetter using the config.
func ExperimentGetter(ctx context.Context, cfg *config.Config) middleware.ExperimentGetter {
	if cfg.DynamicConfigLocation == "" {
		log.Warningf(ctx, "experiments are not configured")
		return func(context.Context) ([]*internal.Experiment, error) { return nil, nil }
	}
	log.Debugf(ctx, "using dynamic config from %s for experiments", cfg.DynamicConfigLocation)
	return func(ctx context.Context) ([]*internal.Experiment, error) {
		dc, err := dynconfig.Read(ctx, cfg.DynamicConfigLocation)
		if err != nil {
			return nil, err
		}

		var s []string
		for _, e := range dc.Experiments {
			s = append(s, fmt.Sprintf("%s:%d", e.Name, e.Rollout))
			if desc, ok := internal.Experiments[e.Name]; ok {
				if e.Description == "" {
					e.Description = desc
				}
			} else {
				log.Errorf(ctx, "unknown experiment %q", e.Name)
			}
		}
		log.Debugf(ctx, "read experiments %s", strings.Join(s, ", "))
		return dc.Experiments, nil
	}
}

// OpenDB opens the postgres database specified by the config.
// It first tries the main connection info (DBConnInfo), and if that fails, it uses backup
// connection info it if exists (DBSecondaryConnInfo).
func OpenDB(ctx context.Context, cfg *config.Config, bypassLicenseCheck bool) (_ *postgres.DB, err error) {
	defer derrors.Wrap(&err, "cmdconfig.OpenDB(ctx, cfg)")

	// Wrap the postgres driver with our own wrapper, which adds OpenCensus instrumentation.
	ocDriver, err := database.RegisterOCWrapper("pgx", ocsql.WithAllTraceOptions())
	if err != nil {
		return nil, fmt.Errorf("unable to register the ocsql driver: %v", err)
	}
	log.Infof(ctx, "opening database on host %s", cfg.DBHost)
	ddb, err := database.Open(ocDriver, cfg.DBConnInfo(), cfg.InstanceID)
	if err == nil {
		log.Infof(ctx, "connected to primary host: %s", cfg.DBHost)
	} else {
		ci := cfg.DBSecondaryConnInfo()
		if ci == "" {
			log.Infof(ctx, "no secondary DB host")
			return nil, err
		}
		log.Errorf(ctx, "database.Open for primary host %s failed with %v; trying secondary host %s ",
			cfg.DBHost, err, cfg.DBSecondaryHost)
		ddb, err = database.Open(ocDriver, ci, cfg.InstanceID)
		if err != nil {
			return nil, err
		}
		log.Infof(ctx, "connected to secondary host %s", cfg.DBSecondaryHost)
	}
	ddb.SetPoolSettings(cfg.DBMaxOpenConns, cfg.DBMaxIdleConns, cfg.DBConnMaxLifetime, cfg.DBConnMaxIdleTime)
	log.Infof(ctx, "database open finished")
	if bypassLicenseCheck {
		return postgres.NewBypassingLicenseCheck(ddb), nil
	}
	return postgres.New(ddb), nil
}
