// Copyright 2021 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 (
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"

	"golang.org/x/benchmarks/sweet/common"
)

func writeSweetConfiguration(filename string, tcs []*toolchain) error {
	var cfg common.ConfigFile
	for _, tc := range tcs {
		cfg.Configs = append(cfg.Configs, &common.Config{
			Name:   tc.Name,
			GoRoot: tc.GOROOT(),
		})
	}
	f, err := os.Create(filename)
	if err != nil {
		return fmt.Errorf("error creating configuration file for Sweet: %w", err)
	}
	defer f.Close()
	b, err := common.ConfigFileMarshalTOML(&cfg)
	if err != nil {
		return fmt.Errorf("error marshaling configuration file for Sweet: %w", err)
	}
	if _, err := f.Write(b); err != nil {
		return fmt.Errorf("error writing configuration file for Sweet: %w", err)
	}
	return nil
}

func sweet(tcs []*toolchain) (err error) {
	tmpDir, err := os.MkdirTemp("", "go-sweet")
	if err != nil {
		return fmt.Errorf("error creating temporary directory: %w", err)
	}
	defer func() {
		err = removeAllIncludingReadonly(tmpDir)
		if err != nil {
			err = fmt.Errorf("error removing temporary directory: %w", err)
		}
	}()
	log.Printf("Sweet temporary directory: %s", tmpDir)

	dirBytes, err := tcs[0].List("-f", "{{.Dir}}", "golang.org/x/benchmarks/sweet/cmd/sweet")
	if err != nil {
		return fmt.Errorf("finding sweet root: %w", err)
	}
	sweetRoot := filepath.Dir(filepath.Dir(string(dirBytes)))
	sweetBin := filepath.Join(tmpDir, "sweet")

	log.Printf("Building Sweet...")

	// Build Sweet itself. N.B. we don't need to do this with the goroot
	// under test since we aren't testing sweet itself, but we are sure that
	// this toolchain exists.
	if err := tcs[0].BuildPackage("golang.org/x/benchmarks/sweet/cmd/sweet", sweetBin); err != nil {
		return fmt.Errorf("building sweet: %v", err)
	}

	log.Printf("Initializing Sweet...")

	var assetsCacheDir string
	if os.Getenv("GO_BUILDER_NAME") != "" {
		// Be explicit that we want /tmp, because the builder is
		// going to try and give us /workdir/tmp which will not
		// have enough space for us.
		assetsCacheDir = filepath.Join("/", "tmp", "go-sweet-assets")
	} else {
		assetsCacheDir = filepath.Join(tmpDir, "assets")
	}
	cmd := exec.Command(
		sweetBin, "get",
		"-cache", assetsCacheDir,
		"-auth", "none",
		"-assets-hash-file", fmt.Sprintf("%s/assets.hash", sweetRoot),
	)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("error running sweet get: %w", err)
	}

	confFile := filepath.Join(tmpDir, "config.toml")
	if err := writeSweetConfiguration(confFile, tcs); err != nil {
		return fmt.Errorf("error writing configuration: %w", err)
	}

	log.Printf("Running Sweet...")

	// Finally we can actually run the benchmarks.
	resultsDir := filepath.Join(tmpDir, "results")
	workDir := filepath.Join(tmpDir, "work")
	cmd = exec.Command(
		sweetBin, "run",
		"-run", "all",
		"-count", "10",
		"-bench-dir", fmt.Sprintf("%s/benchmarks", sweetRoot),
		"-cache", assetsCacheDir,
		"-work-dir", workDir,
		"-results", resultsDir,
		confFile,
	)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("error running sweet run: %w", err)
	}

	// Dump results to stdout.
	for _, tc := range tcs {
		matches, err := filepath.Glob(filepath.Join(resultsDir, "*", fmt.Sprintf("%s.results", tc.Name)))
		if err != nil {
			return fmt.Errorf("searching for results for %s in %s: %v", tc.Name, resultsDir, err)
		}
		fmt.Printf("toolchain: %s\n", tc.Name)
		for _, match := range matches {
			f, err := os.Open(match)
			if err != nil {
				return fmt.Errorf("opening result %s: %v", match, err)
			}
			if _, err := io.Copy(os.Stdout, f); err != nil {
				f.Close()
				return fmt.Errorf("reading result %s: %v", match, err)
			}
			f.Close()
		}
	}
	return nil
}
