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

// perfrun interacts with the buildlet coordinator to run the go1
// benchmarks on a buildlet follower for the most recent successful
// commits according to the build dashboard.
package main

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

	"golang.org/x/build/buildenv"
	"golang.org/x/build/buildlet"
	"golang.org/x/build/types"
)

var (
	buildletBench = flag.String("buildlet", "", "name of buildlet to use for benchmarks")
	buildletSrc   = flag.String("buildlet_src", "", "name of builder to get binaries from (defaults to the same as buildlet)")
	buildEnv      *buildenv.Environment
)

// runBench runs the benchmarks from each of the revisions in
// commits. It uses the tarballs built by the "src" buildlet and runs
// the benchmarks on the "bench" buildlet. It writes a log to out in
// the standard benchmark format
// (https://github.com/golang/proposal/blob/master/design/14313-benchmark-format.md).
func runBench(out io.Writer, bench, src string, commits []string) error {
	ctx := context.TODO()
	bc, err := namedClient(*buildletBench)
	if err != nil {
		return err
	}
	log.Printf("Using buildlet %s", bc.RemoteName())
	workDir, err := bc.WorkDir(ctx)
	if err != nil {
		log.Printf("Getting WorkDir: %v", err)
		return err
	}
	for _, rev := range commits {
		log.Printf("Installing prebuilt rev %s", rev)
		dir := fmt.Sprintf("go-%s", rev)
		// Copy pre-built trees
		if err := bc.PutTarFromURL(ctx, buildEnv.SnapshotURL(src, rev), dir); err != nil {
			log.Printf("failed to extract snapshot for %s: %v", rev, err)
			return err
		}
		// Build binaries
		log.Printf("Building bench binary for rev %s", rev)
		var buf bytes.Buffer
		remoteErr, err := bc.Exec(ctx, path.Join(dir, "bin", "go"), buildlet.ExecOpts{
			Output:   &buf,
			ExtraEnv: []string{"GOROOT=" + path.Join(workDir, dir)},
			Args:     []string{"test", "-c"},
			Dir:      path.Join(dir, "test/bench/go1"),
		})
		if remoteErr != nil {
			log.Printf("failed to compile bench for %s: %v", rev, remoteErr)
			log.Printf("output: %s", buf.Bytes())
			return remoteErr
		}
		if err != nil {
			log.Printf("Exec error: %v", err)
			log.Printf("output: %s", buf.Bytes())
			return err
		}
	}
	// Loop over commits and run N times interleaved, grabbing output
	// TODO: Overhead of multiple Exec calls might be significant; should we ship over a shell script to do this in one go?
	for i := 0; i < 10; i++ {
		log.Printf("Starting bench run %d", i)
		for _, rev := range commits {
			var buf bytes.Buffer
			remoteErr, err := bc.Exec(context.Background(), path.Join("go-"+rev, "test/bench/go1/go1.test"), buildlet.ExecOpts{
				Output: &buf,
				Args:   []string{"-test.bench", ".", "-test.benchmem"},
			})
			if remoteErr != nil {
				log.Printf("failed to run %d-%s: %v", i, rev, remoteErr)
				log.Printf("output: %s", buf.Bytes())
				return remoteErr
			}
			if err != nil {
				log.Printf("Exec error: %v", err)
				log.Printf("output: %s", buf.Bytes())
				return err
			}
			log.Printf("%d-%s: %s", i, rev, buf.Bytes()) // XXX
			fmt.Fprintf(out, "commit: %s\niteration: %d\nstart: %s", rev, i, time.Now().UTC().Format(time.RFC3339))
			out.Write(buf.Bytes())
			out.Write([]byte{'\n'})
		}
	}

	// Destroy client
	// TODO: defer this so we don't leak clients?
	if err := bc.Close(); err != nil {
		return err
	}
	return nil
}

func namedClient(name string) (buildlet.Client, error) {
	if strings.Contains(name, ":") {
		return buildlet.NewClient(name, buildlet.NoKeyPair), nil
	}
	cc, err := buildlet.NewCoordinatorClientFromFlags()
	if err != nil {
		return nil, err
	}
	return cc.CreateBuildlet(name)
	// TODO(quentin): Figure out a way to detect if there's an already running builder with this name.
	//return cc.NamedBuildlet(name)
}

// findCommits finds all the recent successful commits for the given builder
func findCommits(name string) ([]string, error) {
	var bs types.BuildStatus
	res, err := http.Get(buildEnv.DashBase() + "?mode=json")
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if err := json.NewDecoder(res.Body).Decode(&bs); err != nil {
		return nil, err
	}
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("unexpected http status %v", res.Status)
	}

	var commits []string

	for builderIdx := 0; builderIdx < len(bs.Builders); builderIdx++ {
		if bs.Builders[builderIdx] == name {
			for _, br := range bs.Revisions {
				if br.Repo != "go" {
					// Only process go repo for now
					continue
				}
				if br.Results[builderIdx] == "ok" {
					commits = append(commits, br.Revision)
				}
			}
			return commits, nil
		}
	}
	return nil, fmt.Errorf("builder %q not found", name)
}

func usage() {
	fmt.Fprintf(os.Stderr, `Usage of perfrun: perfrun [flags] <commits>

Flags:
`)
	flag.PrintDefaults()
	os.Exit(1)
}

func main() {
	buildlet.RegisterFlags()
	flag.Usage = usage
	flag.Parse()
	buildEnv = buildenv.FromFlags()
	args := flag.Args()
	if *buildletBench == "" {
		usage()
	}
	if *buildletSrc == "" {
		*buildletSrc = *buildletBench
	}
	if len(args) == 0 {
		res, err := findCommits(*buildletSrc)
		args = res
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed finding commits to build: %v", err)
			os.Exit(1)
		}
	}
	log.Printf("Running bench on %v", args)
	out, err := os.Create(fmt.Sprintf("perfrun-%s-%s-%s.log", *buildletSrc, *buildletBench, time.Now().Format("20060102150405")))
	if err != nil {
		fmt.Fprintf(os.Stderr, "Creating log failed: %v", err)
	}
	defer func() {
		if err := out.Close(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed writing log: %v", err)
			os.Exit(1)
		}
	}()
	if err := runBench(out, *buildletBench, *buildletSrc, args); err != nil {
		fmt.Fprintf(os.Stderr, "Failed running bench: %v", err)
		os.Exit(1)
	}
}
