// Copyright 2017 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 gke contains code for interacting with Google Container Engine (GKE),
// the hosted version of Kubernetes on Google Cloud Platform.
//
// The API is not subject to the Go 1 compatibility promise and may change at
// any time. Users should vendor this package and deal with API changes.
package gke

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"encoding/base64"
	"fmt"
	"net/http"

	"cloud.google.com/go/compute/metadata"

	"golang.org/x/build/kubernetes"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	compute "google.golang.org/api/compute/v1"
	"google.golang.org/api/container/v1"
)

// ClientOpt represents an option that can be passed to the Client function.
type ClientOpt interface {
	modify(*clientOpt)
}

type clientOpt struct {
	Project     string
	TokenSource oauth2.TokenSource
	Namespace   string
}

type clientOptFunc func(*clientOpt)

func (f clientOptFunc) modify(o *clientOpt) { f(o) }

// OptProject returns an option setting the GCE Project ID to projectName.
// This is the named project ID, not the numeric ID.
// If unspecified, the current active project ID is used, if the program is running
// on a GCE intance.
func OptProject(projectName string) ClientOpt {
	return clientOptFunc(func(o *clientOpt) {
		o.Project = projectName
	})
}

// OptTokenSource sets the oauth2 token source for making
// authenticated requests to the GKE API. If unset, the default token
// source is used (https://godoc.org/golang.org/x/oauth2/google#DefaultTokenSource).
func OptTokenSource(ts oauth2.TokenSource) ClientOpt {
	return clientOptFunc(func(o *clientOpt) {
		o.TokenSource = ts
	})
}

// OptNamespace sets the Kubernetes namespace to look in.
func OptNamespace(namespace string) ClientOpt {
	return clientOptFunc(func(o *clientOpt) {
		o.Namespace = namespace
	})
}

// NewClient returns an Kubernetes client to a GKE cluster.
func NewClient(ctx context.Context, clusterName string, location string, opts ...ClientOpt) (*kubernetes.Client, error) {
	opt := clientOpt{Namespace: "default"}
	for _, o := range opts {
		o.modify(&opt)
	}
	if opt.TokenSource == nil {
		var err error
		opt.TokenSource, err = google.DefaultTokenSource(ctx, compute.CloudPlatformScope)
		if err != nil {
			return nil, fmt.Errorf("failed to get a token source: %v", err)
		}
	}
	if opt.Project == "" {
		proj, err := metadata.ProjectID()
		if err != nil {
			return nil, fmt.Errorf("metadata.ProjectID: %v", err)
		}
		opt.Project = proj
	}

	httpClient := oauth2.NewClient(ctx, opt.TokenSource)
	containerService, err := container.New(httpClient)
	if err != nil {
		return nil, fmt.Errorf("could not create client for Google Container Engine: %v", err)
	}

	cluster, err := containerService.Projects.Locations.Clusters.Get(fmt.Sprintf("projects/%s/locations/%s/clusters/%s", opt.Project, location, clusterName)).Context(ctx).Do()
	if err != nil {
		return nil, fmt.Errorf("cluster %q could not be found in project %q, location %q: %v", clusterName, opt.Project, location, err)
	}

	// Connect to Kubernetes using OAuth authentication, trusting its CA.
	caPool := x509.NewCertPool()
	caCertPEM, err := base64.StdEncoding.DecodeString(cluster.MasterAuth.ClusterCaCertificate)
	if err != nil {
		return nil, fmt.Errorf("invalid base64 in ClusterCaCertificate: %v", err)
	}
	caPool.AppendCertsFromPEM(caCertPEM)
	kubeHTTPClient := &http.Client{
		Transport: &oauth2.Transport{
			Source: opt.TokenSource,
			Base: &http.Transport{
				TLSClientConfig: &tls.Config{
					RootCAs: caPool,
				},
			},
		},
	}
	kubeClient, err := kubernetes.NewClient("https://"+cluster.Endpoint, opt.Namespace, kubeHTTPClient)
	if err != nil {
		return nil, fmt.Errorf("kubernetes HTTP client could not be created: %v", err)
	}
	return kubeClient, nil
}
