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

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"

	"golang.org/x/benchmarks/sweet/common"
	"golang.org/x/benchmarks/sweet/common/fileutil"
	"golang.org/x/benchmarks/sweet/harnesses"

	osi "github.com/opencontainers/runtime-spec/specs-go"
)

// GVisor is a dynamic assets Generator for the gvisor benchmark.
type GVisor struct{}

// Generate builds binaries for workloads that will run under gVisor
// as part of the benchmark. The sources for these workloads live in
// the source assets directory and are relatively short Go programs.
//
// It also copies over static assets which are necessary to run the
// benchmarks.
func (_ GVisor) Generate(cfg *common.GenConfig) error {
	goTool := *cfg.GoTool
	goTool.Env = goTool.Env.MustSet("CGO_ENABLED=0") // Disable CGO for workloads.

	// Build workload sources into binaries in the output directory,
	// with one binary for each supported platform.
	workloads := []string{
		"http",
		"syscall",
	}
	for _, workload := range workloads {
		workloadSrcDir := filepath.Join(cfg.SourceAssetsDir, workload)
		workloadOutDir := filepath.Join(cfg.OutputDir, workload)
		if err := os.MkdirAll(workloadOutDir, 0755); err != nil {
			return err
		}
		for _, p := range common.SupportedPlatforms {
			// Generate the output directory.
			platformDirName := fmt.Sprintf("%s-%s", p.GOOS, p.GOARCH)
			workloadBinOutDir := filepath.Join(workloadOutDir, "bin", platformDirName)
			if err := os.MkdirAll(workloadBinOutDir, 0755); err != nil {
				return err
			}
			goTool := common.Go{Tool: goTool.Tool, Env: p.BuildEnv(goTool.Env)}

			// Build the workload.
			err := goTool.BuildPath(workloadSrcDir, filepath.Join(workloadBinOutDir, "workload"))
			if err != nil {
				return fmt.Errorf("building workload %s for %s: %v", workload, p, err)
			}
		}
	}

	// In order to regenerate startup/config.json, we require a working
	// copy of runsc. Get and build it from the harness.
	//
	// Create a temporary directory where we can put the gVisor source.
	tmpDir, err := os.MkdirTemp("", "gvisor-gen")
	if err != nil {
		return err
	}
	srcDir := filepath.Join(tmpDir, "src")
	if err := os.MkdirAll(srcDir, os.ModePerm); err != nil {
		return err
	}
	if err := (harnesses.GVisor{}).Get(srcDir); err != nil {
		return err
	}

	// Ensure the startup subdirectory exists.
	if err := os.MkdirAll(filepath.Join(cfg.OutputDir, "startup"), 0755); err != nil {
		return err
	}

	// Build the runsc package in the repository. CGO_ENABLED must be 0.
	// See https://github.com/google/gvisor#using-go-get.
	cfg.GoTool.Env = cfg.GoTool.Env.MustSet("CGO_ENABLED=0")
	runscBin := filepath.Join(tmpDir, "runsc")
	if err := cfg.GoTool.BuildPath(filepath.Join(srcDir, "runsc"), runscBin); err != nil {
		return err
	}

	// Delete config.json if it already exists, because runsc
	// will fail otherwise.
	specFile := filepath.Join(cfg.OutputDir, "startup", "config.json")
	if err := os.Remove(specFile); err != nil && !errors.Is(err, os.ErrNotExist) {
		return err
	}

	// Generate config.json.
	cmd := exec.Command(runscBin, "spec")
	cmd.Dir = filepath.Join(cfg.OutputDir, "startup")
	if err := cmd.Run(); err != nil {
		return err
	}

	// Mutate the config.json slightly for our purposes and write it back out.
	specBytes, err := os.ReadFile(specFile)
	if err != nil {
		return err
	}
	var spec osi.Spec
	if err := json.Unmarshal(specBytes, &spec); err != nil {
		return err
	}
	spec.Process.Terminal = false
	spec.Process.Args = []string{"/hello"}
	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	enc.SetIndent("", "    ")
	if err := enc.Encode(&spec); err != nil {
		return err
	}
	if err := os.WriteFile(specFile, buf.Bytes(), 0666); err != nil {
		return err
	}

	// Everything below this point is static assets. If we're in the
	// same directory, just stop here.
	if cfg.AssetsDir == cfg.OutputDir {
		return nil
	}

	// Generate additional directory structure for static assets
	// that isn't already generated by the build process above.
	if err := os.MkdirAll(filepath.Join(cfg.OutputDir, "http", "assets"), 0755); err != nil {
		return err
	}

	// Copy static assets over.
	staticAssets := []string{
		filepath.Join("http", "assets", "gopherhat.jpg"),
		filepath.Join("http", "assets", "gophermega.jpg"),
		filepath.Join("http", "assets", "gopherswim.jpg"),
		filepath.Join("http", "assets", "gopherhelmet.jpg"),
		filepath.Join("http", "assets", "gopherrunning.jpg"),
		filepath.Join("http", "assets", "gopherswrench.jpg"),
		filepath.Join("http", "README.md"),
		filepath.Join("startup", "README.md"),
		filepath.Join("syscall", "README.md"),
	}
	if err := copyFiles(cfg.OutputDir, cfg.AssetsDir, staticAssets); err != nil {
		return err
	}

	// As a special case, copy everything under startup/rootfs.
	// It's a rootfs, so enumerating everything here would be tedious
	// and not really useful.
	//
	// TODO(mknyszek): Generate this directory from a container image.
	// There's some complications to this, because Cloud Build runs
	// inside docker, and this is generated from a docker image.
	return fileutil.CopyDir(
		filepath.Join(cfg.OutputDir, "startup", "rootfs"),
		filepath.Join(cfg.AssetsDir, "startup", "rootfs"),
		nil,
	)
}
