// 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,
	)
}
