// 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 {
		// Note: This implements a short default in the rare case the caller doesn't care.
		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
}
