// 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"
	"errors"
	"fmt"
	"net"
	"time"

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

// awsClient represents the AWS specific calls made during the
// lifecycle of a buildlet. This is a partial implementation of the AWSClient found at
// `golang.org/x/internal/cloud`.
type awsClient interface {
	Instance(ctx context.Context, instID string) (*cloud.Instance, error)
	CreateInstance(ctx context.Context, config *cloud.EC2VMConfiguration) (*cloud.Instance, error)
	WaitUntilInstanceRunning(ctx context.Context, instID string) error
}

// EC2Client is the client used to create buildlets on EC2.
type EC2Client struct {
	client awsClient
}

// NewEC2Client creates a new EC2Client.
func NewEC2Client(client *cloud.AWSClient) *EC2Client {
	return &EC2Client{
		client: client,
	}
}

// StartNewVM boots a new VM on EC2, waits until the client is accepting connections
// on the configured port and returns a buildlet client configured communicate with it.
func (c *EC2Client) StartNewVM(ctx context.Context, buildEnv *buildenv.Environment, hconf *dashboard.HostConfig, vmName, hostType string, opts *VMOpts) (Client, error) {
	// check required params
	if opts == nil || opts.TLS.IsZero() {
		return nil, errors.New("TLS keypair is not set")
	}
	if buildEnv == nil {
		return nil, errors.New("invalid build environment")
	}
	if hconf == nil {
		return nil, errors.New("invalid host configuration")
	}
	if vmName == "" || hostType == "" {
		return nil, fmt.Errorf("invalid vmName: %q and hostType: %q", vmName, hostType)
	}

	// configure defaults
	if opts.Description == "" {
		opts.Description = fmt.Sprintf("Go Builder for %s", hostType)
	}
	if opts.DeleteIn == 0 {
		opts.DeleteIn = 30 * time.Minute
	}

	vmConfig := configureVM(buildEnv, hconf, vmName, hostType, opts)

	vm, err := c.createVM(ctx, vmConfig, opts)
	if err != nil {
		return nil, err
	}
	if err = c.waitUntilVMExists(ctx, vm.ID, opts); err != nil {
		return nil, err
	}
	// once the VM is up and running then all of the configuration data is available
	// when the API is querried for the VM.
	vm, err = c.client.Instance(ctx, vm.ID)
	if err != nil {
		return nil, fmt.Errorf("unable to retrieve instance %q information: %w", vm.ID, err)
	}
	buildletURL, ipPort, err := ec2BuildletParams(vm, opts)
	if err != nil {
		return nil, err
	}
	return buildletClient(ctx, buildletURL, ipPort, opts)
}

// createVM submits a request for the creation of a VM.
func (c *EC2Client) createVM(ctx context.Context, config *cloud.EC2VMConfiguration, opts *VMOpts) (*cloud.Instance, error) {
	if config == nil || opts == nil {
		return nil, errors.New("invalid parameter")
	}
	inst, err := c.client.CreateInstance(ctx, config)
	if err != nil {
		return nil, fmt.Errorf("unable to create instance: %w", err)
	}
	condRun(opts.OnInstanceRequested)
	return inst, nil
}

// waitUntilVMExists submits a request which waits until an instance exists before returning.
func (c *EC2Client) waitUntilVMExists(ctx context.Context, instID string, opts *VMOpts) error {
	if err := c.client.WaitUntilInstanceRunning(ctx, instID); err != nil {
		return fmt.Errorf("failed waiting for vm instance: %w", err)
	}
	condRun(opts.OnInstanceCreated)
	return nil
}

// configureVM creates a configuration for an EC2 VM instance.
func configureVM(buildEnv *buildenv.Environment, hconf *dashboard.HostConfig, vmName, hostType string, opts *VMOpts) *cloud.EC2VMConfiguration {
	return &cloud.EC2VMConfiguration{
		Description:    opts.Description,
		ImageID:        hconf.VMImage,
		Name:           vmName,
		SSHKeyID:       "ec2-go-builders",
		SecurityGroups: []string{buildEnv.AWSSecurityGroup},
		Tags:           make(map[string]string),
		Type:           hconf.MachineType(),
		UserData:       vmUserDataSpec(buildEnv, hconf, vmName, hostType, opts),
		Zone:           opts.Zone,
	}
}

func vmUserDataSpec(buildEnv *buildenv.Environment, hconf *dashboard.HostConfig, vmName, hostType string, opts *VMOpts) string {
	// add custom metadata to the user data.
	ud := cloud.EC2UserData{
		BuildletName:      vmName,
		BuildletBinaryURL: hconf.BuildletBinaryURL(buildEnv),
		BuildletHostType:  hostType,
		BuildletImageURL:  hconf.ContainerVMImage(),
		Metadata:          make(map[string]string),
		TLSCert:           opts.TLS.CertPEM,
		TLSKey:            opts.TLS.KeyPEM,
		TLSPassword:       opts.TLS.Password(),
	}
	for k, v := range opts.Meta {
		ud.Metadata[k] = v
	}
	return ud.EncodedString()
}

// ec2BuildletParams returns the necessary information to connect to an EC2 buildlet. A
// buildlet URL and an IP address port are required to connect to a buildlet.
func ec2BuildletParams(inst *cloud.Instance, opts *VMOpts) (string, string, error) {
	if inst.IPAddressExternal == "" {
		return "", "", errors.New("external IP address is not set")
	}
	extIP := inst.IPAddressExternal
	buildletURL := fmt.Sprintf("https://%s", extIP)
	ipPort := net.JoinHostPort(extIP, "443")

	if opts.OnGotEC2InstanceInfo != nil {
		opts.OnGotEC2InstanceInfo(inst)
	}
	return buildletURL, ipPort, nil
}
