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

// The rundockerbuildlet command loops forever and creates and cleans
// up Docker containers running reverse buildlets. It keeps a fixed
// number of them running at a time. See x/build/env/linux-arm64/packet/README
// for one example user.
package main

import (
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/aws/aws-sdk-go/aws/ec2metadata"
	"github.com/aws/aws-sdk-go/aws/session"
	"golang.org/x/build/internal/cloud"
)

var (
	image      = flag.String("image", "golang/builder", "docker image to run; required.")
	numInst    = flag.Int("n", 1, "number of containers to keep running at once")
	basename   = flag.String("basename", "builder", "prefix before the builder number to use for the container names and host names")
	memory     = flag.String("memory", "3g", "memory limit flag for docker run")
	keyFile    = flag.String("key", "/etc/gobuild.key", "go build key file")
	builderEnv = flag.String("env", "", "optional GO_BUILDER_ENV environment variable value to set in the guests")
	cpu        = flag.Int("cpu", 0, "if non-zero, how many CPUs to assign from the host and pass to docker run --cpuset-cpus")
	pull       = flag.Bool("pull", false, "whether to pull the --image before each container starting")
)

var (
	buildKey    []byte
	isReverse   = true
	isSingleRun = false
	// ec2UD contains a copy of the EC2 vm user data retrieved from the metadata.
	ec2UD *cloud.EC2UserData
	// ec2MetaClient is an EC2 metadata client.
	ec2MetaClient *ec2metadata.EC2Metadata
)

func main() {
	flag.Parse()

	if onEC2() {
		initEC2Meta()
		*memory = ""
		*image = ec2UD.BuildletImageURL
		*builderEnv = ec2UD.BuildletHostType
		*pull = true
		*numInst = 1
		isReverse = false
		isSingleRun = true
	}

	if isReverse {
		buildKey = getBuildKey()
	}

	if *image == "" {
		log.Fatalf("docker --image is required")
	}

	log.Printf("Started. Will keep %d copies of %s running.", *numInst, *image)
	for {
		if err := checkFix(); err != nil {
			log.Print(err)
		}
		if isSingleRun {
			log.Printf("Configured to run a single instance. Exiting")
			os.Exit(0)
		}
		time.Sleep(time.Second) // TODO: docker wait on the running containers?
	}
}

func ec2MdClient() *ec2metadata.EC2Metadata {
	if ec2MetaClient != nil {
		return ec2MetaClient
	}
	ses, err := session.NewSession()
	if err != nil {
		return nil
	}
	ec2MetaClient = ec2metadata.New(ses)
	return ec2MetaClient
}

func onEC2() bool {
	if ec2MdClient() == nil {
		return false
	}
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	return ec2MdClient().AvailableWithContext(ctx)
}

func getBuildKey() []byte {
	key, err := ioutil.ReadFile(*keyFile)
	if err != nil {
		log.Fatalf("error reading build key from --key=%s: %v", *keyFile, err)
	}
	return bytes.TrimSpace(key)
}

func checkFix() error {
	running := map[string]bool{}

	out, err := exec.Command("docker", "ps", "-a", "--format", "{{.ID}} {{.Names}} {{.Status}}").Output()
	if err != nil {
		return fmt.Errorf("error running docker ps: %v", err)
	}
	// Out is like:
	// b1dc9ec2e646 packet14 Up 23 minutes
	// eeb458938447 packet11 Exited (0) About a minute ago
	// ...
	lines := strings.Split(string(out), "\n")
	for _, line := range lines {
		f := strings.SplitN(line, " ", 3)
		if len(f) < 3 {
			continue
		}
		container, name, status := f[0], f[1], f[2]
		prefix := *basename
		if !strings.HasPrefix(name, prefix) {
			continue
		}
		if strings.HasPrefix(status, "Exited") {
			removeContainer(container)
		}
		running[name] = strings.HasPrefix(status, "Up")
	}

	for num := 1; num <= *numInst; num++ {
		var name string
		if onEC2() {
			name = ec2UD.BuildletName
		} else {
			name = fmt.Sprintf("%s%02d", *basename, num)
		}
		if running[name] {
			continue
		}

		// Just in case we have a container that exists but is not "running"
		// check if it exists and remove it before creating a new one.
		out, err = exec.Command("docker", "ps", "-a", "--filter", "name="+name, "--format", "{{.CreatedAt}}").Output()
		if err == nil && len(bytes.TrimSpace(out)) > 0 {
			// The format for the output is the create time and date:
			// 2017-07-24 17:07:39 +0000 UTC
			// To avoid a race with a container that is "Created" but not yet running
			// check how long ago the container was created.
			// If it's longer than minute, remove it.
			created, err := time.Parse("2006-01-02 15:04:05 -0700 MST", strings.TrimSpace(string(out)))
			if err != nil {
				log.Printf("converting output %q for container %s to time failed: %v", out, name, err)
				continue
			}
			dur := time.Since(created)
			if dur.Minutes() > 0 {
				removeContainer(name)
			}

			log.Printf("Container %s is already being created, duration %s", name, dur.String())
			continue
		}

		if *pull {
			log.Printf("Pulling %s ...", *image)
			out, err := exec.Command("docker", "pull", *image).CombinedOutput()
			if err != nil {
				log.Printf("docker pull %s failed: %v, %s", *image, err, out)
			}
		}

		log.Printf("Creating %s ...", name)
		keyFile := fmt.Sprintf("/tmp/buildkey%02d/gobuildkey", num)
		if err := os.MkdirAll(filepath.Dir(keyFile), 0700); err != nil {
			return err
		}
		if err := ioutil.WriteFile(keyFile, buildKey, 0600); err != nil {
			return err
		}
		cmd := exec.Command("docker", "run",
			"-d",
			"--name="+name,
			"-e", "HOSTNAME="+name,
			"--security-opt=seccomp=unconfined", // Issue 35547
			"--tmpfs=/workdir:rw,exec")
		if *memory != "" {
			cmd.Args = append(cmd.Args, "--memory="+*memory)
		}
		if isReverse {
			cmd.Args = append(cmd.Args, "-v", filepath.Dir(keyFile)+":/buildkey/")
		} else {
			cmd.Args = append(cmd.Args, "-p", "443:443")
		}
		if *cpu > 0 {
			cmd.Args = append(cmd.Args, fmt.Sprintf("--cpuset-cpus=%d-%d", *cpu*(num-1), *cpu*num-1))
		}
		if *builderEnv != "" {
			cmd.Args = append(cmd.Args, "-e", "GO_BUILDER_ENV="+*builderEnv)
		}
		cmd.Args = append(cmd.Args,
			"-e", "GO_BUILD_KEY_PATH=/buildkey/gobuildkey",
			"-e", "GO_BUILD_KEY_DELETE_AFTER_READ=true",
		)
		cmd.Args = append(cmd.Args, *image)
		out, err := cmd.CombinedOutput()
		if err != nil {
			log.Printf("Error creating %s: %v, %s", name, err, out)
			continue
		}
		log.Printf("Created %v", name)
	}
	return nil
}

func initEC2Meta() {
	if !onEC2() {
		log.Fatal("attempt to initialize metadata on non-EC2 instance")
	}
	if ec2UD != nil {
		return
	}
	if ec2MdClient() == nil {
		log.Fatalf("unable to retrieve EC2 metadata client")
	}
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	ec2MetaJson, err := ec2MdClient().GetUserDataWithContext(ctx)
	if err != nil {
		log.Fatalf("unable to retrieve EC2 user data: %v", err)
	}
	ec2UD = &cloud.EC2UserData{}
	err = json.Unmarshal([]byte(ec2MetaJson), ec2UD)
	if err != nil {
		log.Fatalf("unable to unmarshal user data json: %v", err)
	}
}

func removeContainer(container string) {
	if out, err := exec.Command("docker", "rm", "-f", container).CombinedOutput(); err != nil {
		log.Printf("error running docker rm -f %s: %v, %s", container, err, out)
		return
	}
	log.Printf("Removed container %s", container)
}
