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

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"testing"
	"time"

	"golang.org/x/build/buildenv"
	"golang.org/x/build/dashboard"
	"golang.org/x/build/internal/cloud"
)

func TestStartNewVM(t *testing.T) {
	kp, err := NewKeyPair()
	if err != nil {
		t.Fatalf("unable to generate key pair: %s", err)
	}
	buildEnv := &buildenv.Environment{}
	hconf := &dashboard.HostConfig{
		VMImage: "image-x",
	}
	vmName := "sample-vm"
	hostType := "host-sample-os"
	opts := &VMOpts{
		Zone:        "us-west",
		ProjectID:   "project1",
		TLS:         kp,
		Description: "Golang builder for sample",
		Meta: map[string]string{
			"Owner": "george",
		},
		DeleteIn:                 45 * time.Second,
		SkipEndpointVerification: true,
	}
	c := &EC2Client{
		client: cloud.NewFakeAWSClient(),
	}
	gotClient, gotErr := c.StartNewVM(context.Background(), buildEnv, hconf, vmName, hostType, opts)
	if gotErr != nil {
		t.Fatalf("error is not nil: %v", gotErr)
	}
	if gotClient == nil {
		t.Fatalf("response is nil")
	}
}

func TestStartNewVMError(t *testing.T) {
	kp, err := NewKeyPair()
	if err != nil {
		t.Fatalf("unable to generate key pair: %s", err)
	}

	testCases := []struct {
		desc     string
		buildEnv *buildenv.Environment
		hconf    *dashboard.HostConfig
		vmName   string
		hostType string
		opts     *VMOpts
	}{
		{
			desc:     "nil-buildenv",
			hconf:    &dashboard.HostConfig{},
			vmName:   "sample-vm",
			hostType: "host-sample-os",
			opts: &VMOpts{
				Zone:        "us-west",
				ProjectID:   "project1",
				TLS:         kp,
				Description: "Golang builder for sample",
				Meta: map[string]string{
					"Owner": "george",
				},
				DeleteIn: 45 * time.Second,
			},
		},
		{
			desc:     "nil-hconf",
			buildEnv: &buildenv.Environment{},
			vmName:   "sample-vm",
			hostType: "host-sample-os",
			opts: &VMOpts{
				Zone:        "us-west",
				ProjectID:   "project1",
				TLS:         kp,
				Description: "Golang builder for sample",
				Meta: map[string]string{
					"Owner": "george",
				},
				DeleteIn: 45 * time.Second,
			},
		},
		{
			desc:     "empty-vnName",
			buildEnv: &buildenv.Environment{},
			hconf:    &dashboard.HostConfig{},
			vmName:   "",
			hostType: "host-sample-os",
			opts: &VMOpts{
				Zone:        "us-west",
				ProjectID:   "project1",
				TLS:         kp,
				Description: "Golang builder for sample",
				Meta: map[string]string{
					"Owner": "george",
				},
				DeleteIn: 45 * time.Second,
			},
		},
		{
			desc:     "empty-hostType",
			buildEnv: &buildenv.Environment{},
			hconf:    &dashboard.HostConfig{},
			vmName:   "sample-vm",
			hostType: "",
			opts: &VMOpts{
				Zone:        "us-west",
				ProjectID:   "project1",
				TLS:         kp,
				Description: "Golang builder for sample",
				Meta: map[string]string{
					"Owner": "george",
				},
				DeleteIn: 45 * time.Second,
			},
		},
		{
			desc:     "missing-certs",
			buildEnv: &buildenv.Environment{},
			hconf:    &dashboard.HostConfig{},
			vmName:   "sample-vm",
			hostType: "host-sample-os",
			opts: &VMOpts{
				Zone:        "us-west",
				ProjectID:   "project1",
				Description: "Golang builder for sample",
				Meta: map[string]string{
					"Owner": "george",
				},
				DeleteIn: 45 * time.Second,
			},
		},
		{
			desc:     "nil-opts",
			buildEnv: &buildenv.Environment{},
			hconf:    &dashboard.HostConfig{},
			vmName:   "sample-vm",
			hostType: "host-sample-os",
		},
	}
	for _, tc := range testCases {
		t.Run(tc.desc, func(t *testing.T) {
			c := &EC2Client{
				client: cloud.NewFakeAWSClient(),
			}
			gotClient, gotErr := c.StartNewVM(context.Background(), tc.buildEnv, tc.hconf, tc.vmName, tc.hostType, tc.opts)
			if gotErr == nil {
				t.Errorf("StartNewVM(ctx, %+v, %+v, %s, %s, %+v) = %+v, nil; want error", tc.buildEnv, tc.hconf, tc.vmName, tc.hostType, tc.opts, gotClient)
			}
			if gotClient != nil {
				t.Errorf("got %+v; expected nil", gotClient)
			}
		})
	}
}

func TestWaitUntilInstanceExists(t *testing.T) {
	vmConfig := &cloud.EC2VMConfiguration{
		ImageID: "foo",
		Type:    "type-a",
		Zone:    "eu-15",
	}
	invoked := false
	opts := &VMOpts{
		OnInstanceCreated: func() {
			invoked = true
		},
	}
	ctx := context.Background()
	c := &EC2Client{
		client: cloud.NewFakeAWSClient(),
	}
	gotVM, gotErr := c.createVM(ctx, vmConfig, opts)
	if gotErr != nil {
		t.Fatalf("createVM(ctx, %v, %v) failed with %s", vmConfig, opts, gotErr)
	}
	gotErr = c.waitUntilVMExists(ctx, gotVM.ID, opts)
	if gotErr != nil {
		t.Fatalf("WaitUntilVMExists(%v, %v, %v) failed with error %s", ctx, gotVM.ID, opts, gotErr)
	}
	if !invoked {
		t.Errorf("OnInstanceCreated() was not invoked")
	}
}

func TestCreateVM(t *testing.T) {
	vmConfig := &cloud.EC2VMConfiguration{
		ImageID: "foo",
		Type:    "type-a",
		Zone:    "eu-15",
	}
	invoked := false
	opts := &VMOpts{
		OnInstanceRequested: func() {
			invoked = true
		},
	}
	c := &EC2Client{
		client: cloud.NewFakeAWSClient(),
	}
	gotVM, gotErr := c.createVM(context.Background(), vmConfig, opts)
	if gotErr != nil {
		t.Fatalf("createVM(ctx, %v, %v) failed with %s", vmConfig, opts, gotErr)
	}
	if gotVM.ImageID != vmConfig.ImageID || gotVM.Type != vmConfig.Type || gotVM.Zone != vmConfig.Zone {
		t.Errorf("createVM(ctx, %+v, %+v) = %+v, nil; want vm to match config", vmConfig, opts, gotVM)
	}
	if !invoked {
		t.Errorf("OnInstanceRequested() was not invoked")
	}
}

func TestCreateVMError(t *testing.T) {
	testCases := []struct {
		desc     string
		vmConfig *cloud.EC2VMConfiguration
		opts     *VMOpts
	}{
		{
			desc: "missing-vmConfig",
		},
		{
			desc: "missing-image-id",
			vmConfig: &cloud.EC2VMConfiguration{
				Type: "type-a",
				Zone: "eu-15",
			},
			opts: &VMOpts{
				OnInstanceRequested: func() {},
			},
		},
		{
			desc: "missing-instance-id",
			vmConfig: &cloud.EC2VMConfiguration{
				ImageID: "foo",
				Zone:    "eu-15",
			},
			opts: &VMOpts{
				OnInstanceRequested: func() {},
			},
		},
		{
			desc: "missing-placement",
			vmConfig: &cloud.EC2VMConfiguration{
				Name: "foo",
				Type: "type-a",
			},
			opts: &VMOpts{
				OnInstanceRequested: func() {},
			},
		},
	}
	for _, tc := range testCases {
		t.Run(tc.desc, func(t *testing.T) {
			c := &EC2Client{
				client: cloud.NewFakeAWSClient(),
				//client: &fakeAWSClient{},
			}
			gotVM, gotErr := c.createVM(context.Background(), tc.vmConfig, tc.opts)
			if gotErr == nil {
				t.Errorf("createVM(ctx, %v, %v) = %s, %v; want error", tc.vmConfig, tc.opts, gotVM.ID, gotErr)
			}
			if gotVM != nil {
				t.Errorf("createVM(ctx, %v, %v) = %s, %v; %q, error", tc.vmConfig, tc.opts, gotVM.ID, gotErr, "")
			}
		})
	}
}

func TestEC2BuildletParams(t *testing.T) {
	testCases := []struct {
		desc       string
		inst       *cloud.Instance
		opts       *VMOpts
		wantURL    string
		wantPort   string
		wantCalled bool
		wantErr    bool
	}{
		{
			desc: "base-case",
			inst: &cloud.Instance{
				IPAddressExternal: "8.8.8.8",
				IPAddressInternal: "3.3.3.3",
			},
			opts:       &VMOpts{},
			wantCalled: true,
			wantURL:    "https://8.8.8.8",
			wantPort:   "8.8.8.8:443",
			wantErr:    false,
		},
		{
			desc: "missing-int-ip",
			inst: &cloud.Instance{
				IPAddressExternal: "8.8.8.8",
			},
			opts:       &VMOpts{},
			wantCalled: true,
			wantURL:    "https://8.8.8.8",
			wantPort:   "8.8.8.8:443",
			wantErr:    false,
		},
		{
			desc: "missing-ext-ip",
			inst: &cloud.Instance{
				IPAddressInternal: "3.3.3.3",
			},
			opts:       &VMOpts{},
			wantCalled: true,
			wantURL:    "",
			wantPort:   "",
			wantErr:    true,
		},
	}
	for _, tc := range testCases {
		t.Run(tc.desc, func(t *testing.T) {
			gotURL, gotPort, gotErr := ec2BuildletParams(tc.inst, tc.opts)
			if gotURL != tc.wantURL || gotPort != tc.wantPort || tc.wantErr != (gotErr != nil) {
				t.Errorf("ec2BuildletParams(%v, %v) = %q, %q, nil; want %q, %q, nil", tc.inst, tc.opts, gotURL, gotPort, tc.wantURL, tc.wantPort)
			}
		})
	}
}

func TestConfigureVM(t *testing.T) {
	testCases := []struct {
		desc              string
		buildEnv          *buildenv.Environment
		hconf             *dashboard.HostConfig
		hostType          string
		opts              *VMOpts
		vmName            string
		wantDesc          string
		wantImageID       string
		wantInstanceType  string
		wantName          string
		wantZone          string
		wantBuildletName  string
		wantBuildletImage string
	}{
		{
			desc:     "default-values",
			buildEnv: &buildenv.Environment{},
			hconf: &dashboard.HostConfig{
				KonletVMImage: "gcr.io/symbolic-datum-552/gobuilder-arm64-aws",
			},
			vmName:            "base_vm",
			hostType:          "host-foo-bar",
			opts:              &VMOpts{},
			wantInstanceType:  "e2-standard-8",
			wantName:          "base_vm",
			wantBuildletName:  "base_vm",
			wantBuildletImage: "gcr.io/symbolic-datum-552/gobuilder-arm64-aws",
		},
		{
			desc:     "full-configuration",
			buildEnv: &buildenv.Environment{},
			hconf: &dashboard.HostConfig{
				VMImage:       "awesome_image",
				KonletVMImage: "gcr.io/symbolic-datum-552/gobuilder-arm64-aws",
			},
			vmName:   "base-vm",
			hostType: "host-foo-bar",
			opts: &VMOpts{
				Zone: "sa-west",
				TLS: KeyPair{
					CertPEM: "abc",
					KeyPEM:  "xyz",
				},
				Description: "test description",
				Meta: map[string]string{
					"sample": "value",
				},
			},
			wantDesc:          "test description",
			wantImageID:       "awesome_image",
			wantInstanceType:  "e2-standard-8",
			wantName:          "base-vm",
			wantZone:          "sa-west",
			wantBuildletName:  "base-vm",
			wantBuildletImage: "gcr.io/symbolic-datum-552/gobuilder-arm64-aws",
		},
	}
	for _, tc := range testCases {
		t.Run(tc.desc, func(t *testing.T) {
			got := configureVM(tc.buildEnv, tc.hconf, tc.vmName, tc.hostType, tc.opts)
			if got.ImageID != tc.wantImageID {
				t.Errorf("ImageId got %s; want %s", got.ImageID, tc.wantImageID)
			}
			if got.Type != tc.wantInstanceType {
				t.Errorf("Type got %s; want %s", got.Type, tc.wantInstanceType)
			}
			if got.Zone != tc.wantZone {
				t.Errorf("Zone got %s; want %s", got.Zone, tc.wantZone)
			}
			if got.Name != tc.wantName {
				t.Errorf("Name got %s; want %s", got.Name, tc.wantName)
			}
			if got.Description != tc.wantDesc {
				t.Errorf("Description got %s; want %s", got.Description, tc.wantDesc)
			}
			gotUDJson, err := base64.StdEncoding.DecodeString(got.UserData)
			if err != nil {
				t.Fatalf("unable to base64 decode string %q: %s", got.UserData, err)
			}
			gotUD := &cloud.EC2UserData{}
			err = json.Unmarshal([]byte(gotUDJson), gotUD)
			if err != nil {
				t.Errorf("unable to unmarshal user data: %v", err)
			}
			if gotUD.BuildletBinaryURL != tc.hconf.BuildletBinaryURL(tc.buildEnv) {
				t.Errorf("buildletBinaryURL got %s; want %s", gotUD.BuildletBinaryURL, tc.hconf.BuildletBinaryURL(tc.buildEnv))
			}
			if gotUD.BuildletHostType != tc.hostType {
				t.Errorf("buildletHostType got %s; want %s", gotUD.BuildletHostType, tc.hostType)
			}
			if gotUD.BuildletName != tc.wantBuildletName {
				t.Errorf("buildletName got %s; want %s", gotUD.BuildletName, tc.wantBuildletName)
			}
			if gotUD.BuildletImageURL != tc.wantBuildletImage {
				t.Errorf("buildletImageURL got %s; want %s", gotUD.BuildletImageURL, tc.wantBuildletImage)
			}

			if gotUD.TLSCert != tc.opts.TLS.CertPEM {
				t.Errorf("TLSCert got %s; want %s", gotUD.TLSCert, tc.opts.TLS.CertPEM)
			}
			if gotUD.TLSKey != tc.opts.TLS.KeyPEM {
				t.Errorf("TLSKey got %s; want %s", gotUD.TLSKey, tc.opts.TLS.KeyPEM)
			}
			if gotUD.TLSPassword != tc.opts.TLS.Password() {
				t.Errorf("TLSPassword got %s; want %s", gotUD.TLSPassword, tc.opts.TLS.Password())
			}
		})
	}
}
