// Copyright 2015 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 main

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"sync"
	"time"

	"golang.org/x/build/internal/gomote/protos"
	"golang.org/x/sync/errgroup"
)

type builderType struct {
	Name      string
	IsReverse bool
	ExpectNum int
}

func builders() (bt []builderType) {
	type builderInfo struct {
		HostType string
	}
	type hostInfo struct {
		IsReverse      bool
		ExpectNum      int
		ContainerImage string
		VMImage        string
	}
	// resj is the response JSON from the builders.
	var resj struct {
		Builders map[string]builderInfo
		Hosts    map[string]hostInfo
	}
	res, err := http.Get("https://farmer.golang.org/builders?mode=json")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		log.Fatalf("fetching builder types: %s", res.Status)
	}
	if err := json.NewDecoder(res.Body).Decode(&resj); err != nil {
		log.Fatalf("decoding builder types: %v", err)
	}
	for b, bi := range resj.Builders {
		if strings.HasPrefix(b, "misc-compile") {
			continue
		}
		hi, ok := resj.Hosts[bi.HostType]
		if !ok {
			continue
		}
		if !hi.IsReverse && hi.ContainerImage == "" && hi.VMImage == "" {
			continue
		}
		bt = append(bt, builderType{
			Name:      b,
			IsReverse: hi.IsReverse,
			ExpectNum: hi.ExpectNum,
		})
	}
	sort.Slice(bt, func(i, j int) bool {
		return bt[i].Name < bt[j].Name
	})
	return
}

func swarmingBuilders() ([]string, error) {
	ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
	client := gomoteServerClient(ctx)
	resp, err := client.ListSwarmingBuilders(ctx, &protos.ListSwarmingBuildersRequest{})
	if err != nil {
		return nil, fmt.Errorf("unable to retrieve swarming builders: %s", err)
	}
	return resp.Builders, nil
}

func create(args []string) error {
	fs := flag.NewFlagSet("create", flag.ContinueOnError)

	fs.Usage = func() {
		fmt.Fprintln(os.Stderr, "create usage: gomote create [create-opts] <type>")
		fmt.Fprintln(os.Stderr)
		fmt.Fprintln(os.Stderr, "If there's a valid group specified, new instances are")
		fmt.Fprintln(os.Stderr, "automatically added to the group. If the group in")
		fmt.Fprintln(os.Stderr, "$GOMOTE_GROUP doesn't exist, and there's no other group")
		fmt.Fprintln(os.Stderr, "specified, it will be created and new instances will be")
		fmt.Fprintln(os.Stderr, "added to that group.")
		fs.PrintDefaults()
		fmt.Fprintln(os.Stderr, "\nValid types:")
		if luciDisabled() {
			for _, bt := range builders() {
				var warn string
				if bt.IsReverse {
					if bt.ExpectNum > 0 {
						warn = fmt.Sprintf("   [limited capacity: %d machines]", bt.ExpectNum)
					} else {
						warn = "   [limited capacity]"
					}
				}
				fmt.Fprintf(os.Stderr, "  * %s%s\n", bt.Name, warn)
			}
			os.Exit(1)
		} else {
			swarmingBuilders, err := swarmingBuilders()
			if err != nil {
				fmt.Fprintf(os.Stderr, " %s\n", err)
			} else {
				for _, builder := range swarmingBuilders {
					fmt.Fprintf(os.Stderr, "  * %s\n", builder)
				}
			}
			os.Exit(1)
		}
	}
	var status bool
	fs.BoolVar(&status, "status", true, "print regular status updates while waiting")
	var count int
	fs.IntVar(&count, "count", 1, "number of instances to create")
	var setup bool
	fs.BoolVar(&setup, "setup", false, "set up the instance by pushing GOROOT and building the Go toolchain")
	var newGroup string
	fs.StringVar(&newGroup, "new-group", "", "also create a new group and add the new instances to it")
	var useGolangbuild bool
	fs.BoolVar(&useGolangbuild, "use-golangbuild", true, "disable the installation of build dependencies installed by golangbuild")

	fs.Parse(args)
	if fs.NArg() != 1 {
		fs.Usage()
	}
	builderType := fs.Arg(0)

	var groupMu sync.Mutex
	group := activeGroup
	var err error
	if newGroup != "" {
		group, err = doCreateGroup(newGroup)
		if err != nil {
			return err
		}
	}
	if group == nil && os.Getenv("GOMOTE_GROUP") != "" {
		group, err = doCreateGroup(os.Getenv("GOMOTE_GROUP"))
		if err != nil {
			return err
		}
	}

	var tmpOutDir string
	var tmpOutDirOnce sync.Once
	eg, ctx := errgroup.WithContext(context.Background())
	client := gomoteServerClient(ctx)
	for i := 0; i < count; i++ {
		i := i
		eg.Go(func() error {
			start := time.Now()
			var exp []string
			if !useGolangbuild {
				exp = append(exp, "disable-golang-build")
			}
			stream, err := client.CreateInstance(ctx, &protos.CreateInstanceRequest{BuilderType: builderType, ExperimentOption: exp})
			if err != nil {
				return fmt.Errorf("failed to create buildlet: %w", err)
			}
			var inst string
		updateLoop:
			for {
				update, err := stream.Recv()
				switch {
				case err == io.EOF:
					break updateLoop
				case err != nil:
					return fmt.Errorf("failed to create buildlet (%d): %w", i+1, err)
				case update.GetStatus() != protos.CreateInstanceResponse_COMPLETE && status:
					fmt.Fprintf(os.Stderr, "# still creating %s (%d) after %v; %d requests ahead of you\n", builderType, i+1, time.Since(start).Round(time.Second), update.GetWaitersAhead())
				case update.GetStatus() == protos.CreateInstanceResponse_COMPLETE:
					inst = update.GetInstance().GetGomoteId()
				}
			}
			fmt.Println(inst)
			if group != nil {
				groupMu.Lock()
				group.Instances = append(group.Instances, inst)
				groupMu.Unlock()
			}
			if !setup {
				return nil
			}

			// -setup is set, so push GOROOT and run make.bash.

			tmpOutDirOnce.Do(func() {
				tmpOutDir, err = os.MkdirTemp("", "gomote")
			})
			if err != nil {
				return fmt.Errorf("failed to create a temporary directory for setup output: %w", err)
			}

			// Push GOROOT.
			detailedProgress := count == 1
			goroot, err := getGOROOT()
			if err != nil {
				return err
			}
			if !detailedProgress {
				fmt.Fprintf(os.Stderr, "# Pushing GOROOT %q to %q...\n", goroot, inst)
			}
			if err := doPush(ctx, inst, goroot, false, detailedProgress); err != nil {
				return err
			}

			// Run make.bash or make.bat.
			cmd := "go/src/make.bash"
			if strings.Contains(builderType, "windows") {
				cmd = "go/src/make.bat"
			}

			// Create a file to write output to so it doesn't get lost.
			outf, err := os.Create(filepath.Join(tmpOutDir, fmt.Sprintf("%s.stdout", inst)))
			if err != nil {
				return err
			}
			defer func() {
				outf.Close()
				fmt.Fprintf(os.Stderr, "# Wrote results from %q to %q.\n", inst, outf.Name())
			}()
			fmt.Fprintf(os.Stderr, "# Streaming results from %q to %q...\n", inst, outf.Name())

			// If this is the only command running, print to stdout too, for convenience and
			// backwards compatibility.
			outputs := []io.Writer{outf}
			if detailedProgress {
				outputs = append(outputs, os.Stdout)
			} else {
				fmt.Fprintf(os.Stderr, "# Running %q on %q...\n", cmd, inst)
			}
			return doRun(ctx, inst, cmd, []string{}, runWriters(outputs...))
		})
	}
	if err := eg.Wait(); err != nil {
		return err
	}
	if group != nil {
		return storeGroup(group)
	}
	return nil
}
