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

//go:build linux || darwin
// +build linux darwin

package pool

import (
	"context"
	"fmt"
	"log"
	"math/rand"
	"strings"
	"time"

	"golang.org/x/build/buildlet"
	"golang.org/x/build/dashboard"
)

// Buildlet defines an interface for a pool of buildlets.
type Buildlet interface {
	// GetBuildlet returns a new buildlet client.
	//
	// The hostType is the key into the dashboard.Hosts
	// map (such as "host-linux-bullseye"), NOT the buidler type
	// ("linux-386").
	//
	// Users of GetBuildlet must both call Client.Close when done
	// with the client as well as cancel the provided Context.
	GetBuildlet(ctx context.Context, hostType string, lg Logger) (buildlet.Client, error)

	String() string // TODO(bradfitz): more status stuff
}

// IsRemoteBuildletFunc should report whether the buildlet instance name is
// is a remote buildlet. This is applicable to GCE and EC2 instances.
//
// TODO(golang.org/issue/38337): should be removed once remote buildlet management
// functions are moved into a package.
type IsRemoteBuildletFunc func(instanceName string) bool

// randHex generates a random hex string.
func randHex(n int) string {
	buf := make([]byte, n/2+1)
	if _, err := rand.Read(buf); err != nil {
		log.Fatalf("randHex: %v", err)
	}
	return fmt.Sprintf("%x", buf)[:n]
}

func friendlyDuration(d time.Duration) string {
	if d > 10*time.Second {
		d2 := ((d + 50*time.Millisecond) / (100 * time.Millisecond)) * (100 * time.Millisecond)
		return d2.String()
	}
	if d > time.Second {
		d2 := ((d + 5*time.Millisecond) / (10 * time.Millisecond)) * (10 * time.Millisecond)
		return d2.String()
	}
	d2 := ((d + 50*time.Microsecond) / (100 * time.Microsecond)) * (100 * time.Microsecond)
	return d2.String()
}

// instanceName generates a random instance name according to the host type.
func instanceName(hostType string, length int) string {
	return fmt.Sprintf("buildlet-%s-rn%s", strings.TrimPrefix(hostType, "host-"), randHex(length))
}

// determineDeleteTimeout reports the buildlet delete timeout duration
// with the following priority:
//
// 1. Host type override from host config.
// 2. Global default.
func determineDeleteTimeout(host *dashboard.HostConfig) time.Duration {
	if host.CustomDeleteTimeout != 0 {
		return host.CustomDeleteTimeout
	}

	// The value we return below is effectively a global default.
	//
	// The comment of CleanUpOldVMs (and CleanUpOldPodsLoop) includes:
	//
	//	This is the safety mechanism to delete VMs which stray from the
	//	normal deleting process. VMs are created to run a single build and
	//	should be shut down by a controlling process. Due to various types
	//	of failures, they might get stranded. To prevent them from getting
	//	stranded and wasting resources forever, we instead set the
	//	"delete-at" metadata attribute on them when created to some time
	//	that's well beyond their expected lifetime.
	//
	// Issue go.dev/issue/52929 tracks what to do about this global
	// timeout in the long term. Unless something changes,
	// it needs to be maintained manually so that it's always
	// "well beyond their expected lifetime" of each builder that doesn't
	// otherwise override this timeout—otherwise it'll cause even more
	// resources to be used due the automatic (and unlimited) retrying
	// as described in go.dev/issue/42699.
	//
	// A global timeout of 45 minutes was chosen in 2015.
	// Longtest builders were added in 2018 started to reach 45 mins by 2021-2022.
	// Try 2 hours next, which might last some years (depending on test volume and test speed).
	return 2 * time.Hour
}

// isBuildlet checks the name string in order to determine if the name is for a buildlet.
func isBuildlet(name string) bool {
	return strings.HasPrefix(name, "buildlet-")
}

// TestPoolHook is used to override the buildlet returned by ForConf. It should only be used for
// testing purposes.
var TestPoolHook func(*dashboard.HostConfig) Buildlet

// ForHost returns the appropriate buildlet depending on the host configuration that is passed it.
// The returned buildlet can be overridden for testing purposes by registering a test hook.
func ForHost(conf *dashboard.HostConfig) Buildlet {
	if TestPoolHook != nil {
		return TestPoolHook(conf)
	}
	if conf == nil {
		panic("nil conf")
	}
	switch {
	case conf.IsEC2():
		return EC2BuildetPool()
	case conf.IsVM():
		return NewGCEConfiguration().BuildletPool()
	case conf.IsContainer():
		if NewGCEConfiguration().BuildEnv().PreferContainersOnCOS || KubeErr() != nil {
			return NewGCEConfiguration().BuildletPool() // it also knows how to do containers.
		} else {
			return KubePool()
		}
	case conf.IsReverse:
		return ReversePool()
	default:
		panic(fmt.Sprintf("no buildlet pool for host type %q", conf.HostType))
	}
}
