// Copyright 2022 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 sandbox runs programs in a secure environment.
package sandbox

import (
	"bytes"
	"encoding/json"
	"fmt"
	"os/exec"

	"golang.org/x/pkgsite-metrics/internal/derrors"
)

// A Sandbox is a restricted execution environment.
// A Sandbox instance refers to a directory containing an OCI
// bundle (see https://github.com/opencontainers/runtime-spec/blob/main/bundle.md).
type Sandbox struct {
	bundleDir string
	Runsc     string // path to runsc program
}

// New returns a new Sandbox using the bundle in bundleDir.
// The bundle must be configured to run the 'runner' program,
// built from runner.go in this directory.
// The Sandbox expects the runsc program to be on the path.
// That can be overridden by setting the Runsc field.
func New(bundleDir string) *Sandbox {
	return &Sandbox{
		bundleDir: bundleDir,
		Runsc:     "runsc",
	}
}

// Cmd's exported fields must be a subset of the exported fields of exec.Cmd.
// runner.go must be able to unmarshal a sandbox.Cmd into an exec.Cmd.

// Cmd describes how to run a binary in a sandbox.
type Cmd struct {
	sb *Sandbox

	// Path is the path of the command to run.
	//
	// This is the only field that must be set to a non-zero
	// value. If Path is relative, it is evaluated relative
	// to Dir.
	Path string

	// Args holds command line arguments, including the command as Args[0].
	// If the Args field is empty or nil, Run uses {Path}.
	//
	// In typical use, both Path and Args are set by calling Command.
	Args []string

	// Env specifies the environment of the process.
	// Each entry is of the form "key=value".
	// If Env is nil, the new process uses whatever environment
	// runsc provides by default.
	Env []string

	// If AppendToEnv is true, the contents of Env are appended
	// to the sandbox's existing environment, instead of replacing it.
	AppendToEnv bool

	// Dir specifies the working directory of the command.
	// If Dir is the empty string, Run runs the command in the
	// root of the sandbox filesystem.
	Dir string
}

// Command creates a *Cmd to run path in the sandbox.
// It behaves like [os/exec.Command].
func (s *Sandbox) Command(path string, arg ...string) *Cmd {
	return &Cmd{
		sb:   s,
		Path: path,
		Args: append([]string{path}, arg...),
	}
}

// Output runs Cmd in the sandbox used to create it, and returns its standard output.
func (c *Cmd) Output() (_ []byte, err error) {
	defer derrors.Wrap(&err, "Cmd.Output %q", c.Args)
	// -ignore-cgroups is needed to avoid this error from runsc:
	// cannot set up cgroup for root: configuring cgroup: write /sys/fs/cgroup/cgroup.subtree_control: device or resource busy
	cmd := exec.Command(c.sb.Runsc, "-ignore-cgroups", "-network=none", "run", "sandbox")
	cmd.Dir = c.sb.bundleDir
	stdinPipe, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}
	stdin, err := json.Marshal(c)
	if err != nil {
		return nil, err
	}
	ch := make(chan error, 1)
	go func() {
		_, err := stdinPipe.Write(stdin)
		stdinPipe.Close()
		ch <- err
	}()
	out, err := cmd.Output()
	if err != nil {
		return nil, err
	}
	if err := <-ch; err != nil {
		return nil, fmt.Errorf("writing stdin: %w", err)
	}
	return bytes.TrimSpace(out), nil
}
