// Copyright 2011 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 buildenv contains definitions for the
// environments the Go build system can run in.
package buildenv

import (
	"context"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"sync"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	compute "google.golang.org/api/compute/v1"
	oauth2api "google.golang.org/api/oauth2/v2"
)

const (
	prefix = "https://www.googleapis.com/compute/v1/projects/"
)

// KubeConfig describes the configuration of a Kubernetes cluster.
type KubeConfig struct {
	// The zone of the cluster. Autopilot clusters have no single zone.
	Zone string

	// The region of the cluster.
	Region string

	// Name is the name of the Kubernetes cluster that will be used.
	Name string

	// Namespace is the Kubernetes namespace to use within the cluster.
	Namespace string
}

// ZoneOrRegion returns the zone or if unset, the region of the cluster.
// This is the string to use as the "zone" of the cluster when connecting to it
// with the Kubernetes API.
func (kc KubeConfig) ZoneOrRegion() string {
	if kc.Zone != "" {
		return kc.Zone
	}
	if kc.Region != "" {
		return kc.Region
	}
	panic(fmt.Sprintf("KubeConfig has neither zone nor region: %#v", kc))
}

// Environment describes the configuration of the infrastructure for a
// coordinator and its buildlet resources running on Google Cloud Platform.
// Staging and Production are the two common build environments.
type Environment struct {
	// The GCP project name that the build infrastructure will be provisioned in.
	// This field may be overridden as necessary without impacting other fields.
	ProjectName string

	// ProjectNumber is the GCP build infrastructure project's number, as visible
	// in the admin console. This is used for things such as constructing the
	// "email" of the default service account.
	ProjectNumber int64

	// The GCP project name for the Go project, where build status is stored.
	// This field may be overridden as necessary without impacting other fields.
	GoProjectName string

	// The IsProd flag indicates whether production functionality should be
	// enabled. When true, GCE and Kubernetes builders are enabled and the
	// coordinator serves on 443. Otherwise, GCE and Kubernetes builders are
	// disabled and the coordinator serves on 8119.
	IsProd bool

	// VMZones are the GCE zones that the VMs will be deployed to. These
	// GCE zones will be periodically cleaned by deleting old VMs. The zones
	// should all exist within a single region.
	VMZones []string

	// StaticIP is the public, static IP address that will be attached to the
	// coordinator instance. The zero value means the address will be looked
	// up by name. This field is optional.
	StaticIP string

	// KubeBuild is the cluster that runs buildlets.
	KubeBuild KubeConfig
	// KubeServices is the cluster that runs the coordinator and other services.
	KubeServices KubeConfig

	// PreferContainersOnCOS controls whether we do most builds on
	// Google's Container-Optimized OS Linux image running on a VM
	// rather than using Kubernetes for builds. This does not
	// affect cross-compiled builds just running make.bash. Those
	// still use Kubernetes for now.
	// See https://golang.org/issue/25108.
	PreferContainersOnCOS bool

	// DashURL is the base URL of the build dashboard, ending in a slash.
	DashURL string

	// PerfDataURL is the base URL of the benchmark storage server.
	PerfDataURL string

	// CoordinatorName is the hostname of the coordinator instance.
	CoordinatorName string

	// BuildletBucket is the GCS bucket that stores buildlet binaries.
	// TODO: rename. this is not just for buildlets; also for bootstrap.
	BuildletBucket string

	// LogBucket is the GCS bucket to which logs are written.
	LogBucket string

	// SnapBucket is the GCS bucket to which snapshots of
	// completed builds (after make.bash, before tests) are
	// written.
	SnapBucket string

	// MaxBuilds is the maximum number of concurrent builds that
	// can run. Zero means unlimited. This is typically only used
	// in a development or staging environment.
	MaxBuilds int

	// AutoCertCacheBucket is the GCS bucket to use for the
	// golang.org/x/crypto/acme/autocert (LetsEncrypt) cache.
	// If empty, LetsEncrypt isn't used.
	AutoCertCacheBucket string

	// COSServiceAccount (Container Optimized OS) is the service
	// account that will be assigned to a VM instance that hosts
	// a container when the instance is created.
	COSServiceAccount string

	// AWSSecurityGroup is the security group name that any VM instance
	// created on EC2 should contain. These security groups are
	// collections of firewall rules to be applied to the VM.
	AWSSecurityGroup string

	// AWSRegion is the region where AWS resources are deployed.
	AWSRegion string
}

// ComputePrefix returns the URI prefix for Compute Engine resources in a project.
func (e Environment) ComputePrefix() string {
	return prefix + e.ProjectName
}

// RandomVMZone returns a randomly selected zone from the zones in VMZones.
func (e Environment) RandomVMZone() string {
	return e.VMZones[rand.Intn(len(e.VMZones))]
}

// SnapshotURL returns the absolute URL of the .tar.gz containing a
// built Go tree for the builderType and Go rev (40 character Git
// commit hash). The tarball is suitable for passing to
// (*buildlet.Client).PutTarFromURL.
func (e Environment) SnapshotURL(builderType, rev string) string {
	return fmt.Sprintf("https://storage.googleapis.com/%s/go/%s/%s.tar.gz", e.SnapBucket, builderType, rev)
}

// DashBase returns the base URL of the build dashboard, ending in a slash.
func (e Environment) DashBase() string {
	// TODO(quentin): Should we really default to production? That's what the old code did.
	if e.DashURL != "" {
		return e.DashURL
	}
	return Production.DashURL
}

// Credentials returns the credentials required to access the GCP environment
// with the necessary scopes.
func (e Environment) Credentials(ctx context.Context) (*google.Credentials, error) {
	// TODO: this method used to do much more. maybe remove it
	// when TODO below is addressed, pushing scopes to caller? Or
	// add a Scopes func/method somewhere instead?
	scopes := []string{
		// Cloud Platform should include all others, but the
		// old code duplicated compute and the storage full
		// control scopes, so I leave them here for now. They
		// predated the all-encompassing "cloud platform"
		// scope anyway.
		// TODO: remove compute and DevstorageFullControlScope once verified to work
		// without.
		compute.CloudPlatformScope,
		compute.ComputeScope,
		compute.DevstorageFullControlScope,

		// The coordinator needed the userinfo email scope for
		// reporting to the perf dashboard running on App
		// Engine at one point. The perf dashboard is down at
		// the moment, but when it's back up we'll need this,
		// and if we do other authenticated requests to App
		// Engine apps, this would be useful.
		oauth2api.UserinfoEmailScope,
	}
	creds, err := google.FindDefaultCredentials(ctx, scopes...)
	if err != nil {
		CheckUserCredentials()
		return nil, err
	}
	creds.TokenSource = diagnoseFailureTokenSource{creds.TokenSource}
	return creds, nil
}

// ByProjectID returns an Environment for the specified
// project ID. It is currently limited to the symbolic-datum-552
// and go-dashboard-dev projects.
// ByProjectID will panic if the project ID is not known.
func ByProjectID(projectID string) *Environment {
	var envKeys []string

	for k := range possibleEnvs {
		envKeys = append(envKeys, k)
	}

	var env *Environment
	env, ok := possibleEnvs[projectID]
	if !ok {
		panic(fmt.Sprintf("Can't get buildenv for unknown project %q. Possible envs are %s", projectID, envKeys))
	}

	return env
}

// Staging defines the environment that the coordinator and build
// infrastructure is deployed to before it is released to production.
// For local dev, override the project with the program's flag to set
// a custom project.
var Staging = &Environment{
	ProjectName:           "go-dashboard-dev",
	ProjectNumber:         302018677728,
	GoProjectName:         "go-dashboard-dev",
	IsProd:                true,
	VMZones:               []string{"us-central1-a", "us-central1-b", "us-central1-c", "us-central1-f"},
	StaticIP:              "104.154.113.235",
	PreferContainersOnCOS: true,
	KubeBuild: KubeConfig{
		Zone:   "us-central1-f",
		Region: "us-central1",
		Name:   "buildlets",
	},
	KubeServices: KubeConfig{
		Zone:      "us-central1-f",
		Region:    "us-central1",
		Name:      "go",
		Namespace: "default",
	},
	DashURL:           "https://build-staging.golang.org/",
	PerfDataURL:       "https://perfdata.golang.org",
	CoordinatorName:   "farmer",
	BuildletBucket:    "dev-go-builder-data",
	LogBucket:         "dev-go-build-log",
	SnapBucket:        "dev-go-build-snap",
	COSServiceAccount: "linux-cos-builders@go-dashboard-dev.iam.gserviceaccount.com",
	AWSSecurityGroup:  "staging-go-builders",
	AWSRegion:         "us-east-1",
}

// Production defines the environment that the coordinator and build
// infrastructure is deployed to for production usage at build.golang.org.
var Production = &Environment{
	ProjectName:           "symbolic-datum-552",
	ProjectNumber:         872405196845,
	GoProjectName:         "golang-org",
	IsProd:                true,
	VMZones:               []string{"us-central1-a", "us-central1-b", "us-central1-c", "us-central1-f"},
	StaticIP:              "107.178.219.46",
	PreferContainersOnCOS: true,
	KubeBuild: KubeConfig{
		Zone:   "us-central1-f",
		Region: "us-central1",
		Name:   "buildlets",
	},
	KubeServices: KubeConfig{
		Region:    "us-central1",
		Name:      "services",
		Namespace: "prod",
	},
	DashURL:             "https://build.golang.org/",
	PerfDataURL:         "https://perfdata.golang.org",
	CoordinatorName:     "farmer",
	BuildletBucket:      "go-builder-data",
	LogBucket:           "go-build-log",
	SnapBucket:          "go-build-snap",
	AutoCertCacheBucket: "farmer-golang-org-autocert-cache",
	COSServiceAccount:   "linux-cos-builders@symbolic-datum-552.iam.gserviceaccount.com",
	AWSSecurityGroup:    "go-builders",
	AWSRegion:           "us-east-2",
}

var Development = &Environment{
	GoProjectName: "golang-org",
	IsProd:        false,
	StaticIP:      "127.0.0.1",
}

// possibleEnvs enumerate the known buildenv.Environment definitions.
var possibleEnvs = map[string]*Environment{
	"dev":                Development,
	"symbolic-datum-552": Production,
	"go-dashboard-dev":   Staging,
}

var (
	stagingFlag     bool
	localDevFlag    bool
	registeredFlags bool
)

// RegisterFlags registers the "staging" and "localdev" flags.
func RegisterFlags() {
	if registeredFlags {
		panic("duplicate call to RegisterFlags or RegisterStagingFlag")
	}
	flag.BoolVar(&localDevFlag, "localdev", false, "use the localhost in-development coordinator")
	RegisterStagingFlag()
	registeredFlags = true
}

// RegisterStagingFlag registers the "staging" flag.
func RegisterStagingFlag() {
	if registeredFlags {
		panic("duplicate call to RegisterFlags or RegisterStagingFlag")
	}
	flag.BoolVar(&stagingFlag, "staging", false, "use the staging build coordinator and buildlets")
	registeredFlags = true
}

// FromFlags returns the build environment specified from flags,
// as registered by RegisterFlags or RegisterStagingFlag.
// By default it returns the production environment.
func FromFlags() *Environment {
	if !registeredFlags {
		panic("FromFlags called without RegisterFlags")
	}
	if localDevFlag {
		return Development
	}
	if stagingFlag {
		return Staging
	}
	return Production
}

// warnCredsOnce guards CheckUserCredentials spamming stderr. Once is enough.
var warnCredsOnce sync.Once

// CheckUserCredentials warns if the gcloud Application Default Credentials file doesn't exist
// and says how to log in properly.
func CheckUserCredentials() {
	adcJSON := filepath.Join(os.Getenv("HOME"), ".config/gcloud/application_default_credentials.json")
	if _, err := os.Stat(adcJSON); os.IsNotExist(err) {
		warnCredsOnce.Do(func() {
			log.Printf("warning: file %s does not exist; did you run 'gcloud auth application-default login' ? (The 'application-default' part matters, confusingly.)", adcJSON)
		})
	}
}

// diagnoseFailureTokenSource is an oauth2.TokenSource wrapper that,
// upon failure, diagnoses why the token acquistion might've failed.
type diagnoseFailureTokenSource struct {
	ts oauth2.TokenSource
}

func (ts diagnoseFailureTokenSource) Token() (*oauth2.Token, error) {
	t, err := ts.ts.Token()
	if err != nil {
		CheckUserCredentials()
		return nil, err
	}
	return t, nil
}
