// 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_test

import (
	"context"
	"os"
	"strings"
	"testing"

	"cloud.google.com/go/compute/metadata"
	"golang.org/x/build/kubernetes"
	"golang.org/x/build/kubernetes/gke"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	compute "google.golang.org/api/compute/v1"
	container "google.golang.org/api/container/v1"
)

// Note: The TestNewClient, TestDialPod, TestDialService, and TestGetNodes
// tests require to be run on GCE and with Application Default Credentials
// that have at least the container.clusters.list permission, at least one
// GKE cluster, and possibly more.
//
// They're currently disabled on the Go builders; see golang.org/issue/28543.

// Tests NewClient and also Dialer.
func TestNewClient(t *testing.T) {
	ctx := context.Background()
	foreachCluster(t, func(cl *container.Cluster, kc *kubernetes.Client) {
		_, err := kc.GetPods(ctx)
		if err != nil {
			t.Fatal(err)
		}
	})
}

func TestDialPod(t *testing.T) {
	var passed bool
	var candidates int
	ctx := context.Background()
	foreachCluster(t, func(cl *container.Cluster, kc *kubernetes.Client) {
		if passed {
			return
		}
		pods, err := kc.GetPods(ctx)
		if err != nil {
			t.Fatal(err)
		}

		for _, pod := range pods {
			if pod.Status.Phase != "Running" {
				continue
			}
			for _, container := range pod.Spec.Containers {
				for _, port := range container.Ports {
					if strings.ToLower(string(port.Protocol)) == "udp" || port.ContainerPort == 0 {
						continue
					}
					candidates++
					c, err := kc.DialPod(ctx, pod.Name, port.ContainerPort)
					if err != nil {
						t.Logf("Dial %q/%q/%d: %v", cl.Name, pod.Name, port.ContainerPort, err)
						continue
					}
					c.Close()
					t.Logf("Dialed %q/%q/%d.", cl.Name, pod.Name, port.ContainerPort)
					passed = true
					return
				}
			}
		}
	})
	if candidates == 0 {
		t.Skip("no pods to dial")
	}
	if !passed {
		t.Errorf("dial failures")
	}
}

func TestDialService(t *testing.T) {
	var passed bool
	var candidates int
	ctx := context.Background()
	foreachCluster(t, func(cl *container.Cluster, kc *kubernetes.Client) {
		if passed {
			return
		}
		svcs, err := kc.GetServices(ctx)
		if err != nil {
			t.Fatal(err)
		}
		for _, svc := range svcs {
			eps, err := kc.GetServiceEndpoints(ctx, svc.Name, "")
			if err != nil {
				t.Fatal(err)
			}
			if len(eps) != 1 {
				continue
			}
			candidates++
			conn, err := kc.DialServicePort(ctx, svc.Name, "")
			if err != nil {
				t.Logf("%s: DialServicePort(%q) error: %v", cl.Name, svc.Name, err)
				continue
			}
			conn.Close()
			passed = true
			t.Logf("Dialed cluster %q service %q.", cl.Name, svc.Name)
			return
		}

	})
	if candidates == 0 {
		t.Skip("no services to dial")
	}
	if !passed {
		t.Errorf("dial failures")
	}
}

func foreachCluster(t *testing.T, fn func(*container.Cluster, *kubernetes.Client)) {
	if testing.Short() {
		t.Skip("skipping in short mode")
	}
	if !metadata.OnGCE() {
		t.Skip("not on GCE; skipping")
	}
	ctx := context.Background()
	ts, err := google.DefaultTokenSource(ctx, compute.CloudPlatformScope)
	if err != nil {
		t.Fatal(err)
	}
	httpClient := oauth2.NewClient(ctx, ts)
	containerService, err := container.New(httpClient)
	if err != nil {
		t.Fatal(err)
	}
	proj, err := metadata.ProjectID()
	if err != nil {
		t.Fatal(err)
	}
	if os.Getenv("GO_BUILDER_NAME") != "" && proj == "symbolic-datum-552" {
		t.Skip("builders on symbolic-datum-552 are not configured for gke tests (golang.org/issue/28543); skipping")
	}
	if _, err := ts.Token(); err != nil {
		val, err := metadata.InstanceAttributeValue("service-accounts/default/token")
		if val == "" {
			t.Skip("skipping on GCE instance without a service account")
		}
		t.Skipf("default token source doesn't work; skipping test: %v", err)
	}

	clusters, err := containerService.Projects.Zones.Clusters.List(proj, "-").Context(ctx).Do()
	if err != nil {
		t.Fatal(err)
	}

	if len(clusters.Clusters) == 0 {
		t.Skip("no GKE clusters")
	}
	for _, cl := range clusters.Clusters {
		kc, err := gke.NewClient(ctx, cl.Name, gke.OptZone(cl.Zone))
		if err != nil {
			t.Fatal(err)
		}
		fn(cl, kc)
		kc.Close()
	}
}

func TestGetNodes(t *testing.T) {
	var passed bool
	ctx := context.Background()
	foreachCluster(t, func(cl *container.Cluster, kc *kubernetes.Client) {
		if passed {
			return
		}
		nodes, err := kc.GetNodes(ctx)
		if err != nil {
			t.Fatal(err)
		}
		t.Logf("%d nodes in cluster %s", len(nodes), cl.Name)
		passed = true
	})
}
