// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package provisioner exports behaviors for provisioning COS systems
// end-to-end. These behaviors are intended to run on a COS system.
package provisioner

import (
	"bufio"
	"context"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"cloud.google.com/go/storage"
	"cos.googlesource.com/cos/tools.git/src/pkg/utils"
	"golang.org/x/sys/unix"
)

// ErrRebootRequired indicates that a reboot is necessary for provisioning to
// continue.
var ErrRebootRequired = errors.New("reboot required to continue provisioning")

// I typically do not like this style of mocking, but I think it's the best
// option in this case. These functions cannot execute at all in a normal test
// environment because they require root privileges. Even if the address to
// mount is owned by the caller, these functions will fail. To take them out of
// the test codepath, we can mock them here.
//
// I have considered an alternative involving writing a unixPkg interface and
// passing it through the Deps struct. But it doesn't give us much for its
// additional verbosity.
var mountFunc = unix.Mount
var unmountFunc = unix.Unmount

func mountOptions(rootDir, mountPoint string) (uintptr, error) {
	mountInfoFile, err := os.Open(filepath.Join(rootDir, "proc/self/mountinfo"))
	if err != nil {
		return 0, err
	}
	defer mountInfoFile.Close()
	scanner := bufio.NewScanner(mountInfoFile)
	var options string
	for scanner.Scan() {
		fields := strings.Fields(scanner.Text())
		if len(fields) < 6 {
			return 0, fmt.Errorf("invalid line in mountinfo: %q", scanner.Text())
		}
		if fields[4] == mountPoint {
			options = fields[5]
			break
		}
	}
	if options == "" {
		return 0, fmt.Errorf("mountpoint %q not found", mountPoint)
	}
	var parsedOptions uintptr
	for _, opt := range strings.FieldsFunc(options, func(r rune) bool { return r == ',' }) {
		// String representations of mount options are viewable here:
		// https://github.com/torvalds/linux/blob/8404c9fbc84b741f66cff7d4934a25dd2c344452/fs/proc_namespace.c#L66
		//
		// "ro" vs "rw" is special cased:
		// https://github.com/torvalds/linux/blob/8404c9fbc84b741f66cff7d4934a25dd2c344452/fs/proc_namespace.c#L159
		switch opt {
		case "nosuid":
			parsedOptions |= unix.MS_NOSUID
		case "nodev":
			parsedOptions |= unix.MS_NODEV
		case "noexec":
			parsedOptions |= unix.MS_NOEXEC
		case "noatime":
			parsedOptions |= unix.MS_NOATIME
		case "nodiratime":
			parsedOptions |= unix.MS_NODIRATIME
		case "relatime":
			parsedOptions |= unix.MS_RELATIME
		case "nosymfollow":
			parsedOptions |= unix.MS_NOSYMFOLLOW
		case "ro":
			parsedOptions |= unix.MS_RDONLY
		}
	}
	return parsedOptions, nil
}

func setup(runState *state, deps Deps, systemd *systemdClient) error {
	log.Println("Setting up environment...")
	if err := systemd.stop("update-engine.service"); err != nil {
		return err
	}
	if err := mountFunc("tmpfs", filepath.Join(deps.RootDir, "root"), "tmpfs", 0, ""); err != nil {
		return fmt.Errorf("error mounting tmpfs at /root: %v", err)
	}
	binPath := filepath.Join(runState.dir, "bin")
	dockerCredentialGCRPath := filepath.Join(binPath, "docker-credential-gcr")
	if _, err := os.Stat(binPath); os.IsNotExist(err) {
		if err := os.Mkdir(binPath, 0744); err != nil {
			return err
		}
	}
	if _, err := os.Stat(dockerCredentialGCRPath); os.IsNotExist(err) {
		if err := utils.CopyFile(deps.DockerCredentialGCR, dockerCredentialGCRPath); err != nil {
			return err
		}
		if err := os.Chmod(dockerCredentialGCRPath, 0755); err != nil {
			return err
		}
	}
	// docker-credential-gcr will complain if docker-credential-gcr is not in the
	// PATH
	pathVar := os.Getenv("PATH")
	if err := os.Setenv("PATH", binPath+":"+pathVar); err != nil {
		return fmt.Errorf("could not update PATH environment variable: %v", err)
	}
	// Ensure that docker-credential-gcr is on an executable mount
	if err := mountFunc(binPath, binPath, "ext4", unix.MS_BIND, ""); err != nil {
		return fmt.Errorf("error bind mounting %q: %v", dockerCredentialGCRPath, err)
	}
	opts, err := mountOptions(deps.RootDir, binPath)
	if err != nil {
		return err
	}
	if err := mountFunc("", binPath, "", unix.MS_REMOUNT|unix.MS_BIND|opts&^unix.MS_NOEXEC, ""); err != nil {
		return fmt.Errorf("error remounting %q as executable: %v", dockerCredentialGCRPath, err)
	}
	// Run docker-credential-gcr
	cmd := exec.Command(dockerCredentialGCRPath, "configure-docker")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("error in cmd docker-credential-gcr, see stderr for details: %v", err)
	}
	log.Println("Done setting up the environment")
	return nil
}

func stopServices(systemd *systemdClient) error {
	log.Println("Stopping services...")
	for _, s := range []string{
		"crash-reporter.service",
		"crash-sender.service",
		"device_policy_manager.service",
		"metrics-daemon.service",
		"update-engine.service",
		"systemd-random-seed.service",
		"systemd-journald-audit.socket",
		"systemd-journald-dev-log.socket",
		"systemd-journald.socket",
		"systemd-journald.service",
	} {
		if err := systemd.stop(s); err != nil {
			return err
		}
	}
	log.Println("Done stopping services.")
	return nil
}

func zeroAllFiles(dir string) error {
	if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
		return nil
	}
	return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return fmt.Errorf("error accessing path %q: %v", path, err)
		}
		if info.IsDir() {
			return nil
		}
		// Truncate the file
		f, err := os.Create(path)
		if err != nil {
			return err
		}
		if err := f.Close(); err != nil {
			return err
		}
		return nil
	})
}

func cleanupDir(dir string, exclude []string) error {
	fileInfos, err := ioutil.ReadDir(dir)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		} else {
			return err
		}
	}
	for _, fi := range fileInfos {
		if utils.StringSliceContains(exclude, fi.Name()) {
			continue
		}
		if err := os.RemoveAll(filepath.Join(dir, fi.Name())); err != nil {
			return err
		}
	}
	return nil
}

func cleanEtcSSH(rootDir string) error {
	dir := filepath.Join(rootDir, "etc", "ssh")
	fileInfos, err := ioutil.ReadDir(dir)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		} else {
			return err
		}
	}
	for _, fi := range fileInfos {
		if strings.HasPrefix(fi.Name(), "ssh_host_") {
			if err := os.RemoveAll(filepath.Join(dir, fi.Name())); err != nil {
				return err
			}
		}
	}
	return nil
}

func cleanup(rootDir, stateDir string) error {
	log.Println("Cleaning up machine state...")
	binPath := filepath.Join(stateDir, "bin")
	if err := unmountFunc(binPath, 0); err != nil {
		return fmt.Errorf("error unmounting %q: %v", binPath, err)
	}
	if err := os.RemoveAll(stateDir); err != nil {
		return err
	}
	if err := unmountFunc(filepath.Join(rootDir, "root"), 0); err != nil {
		// This error can be non-fatal because this is cleaning up a tmpfs mount,
		// which doesn't impact the final image output in any way
		log.Printf("Non-fatal error unmounting tmpfs at /root: %v", err)
	}
	// Files and directories to remove
	for _, f := range []string{
		filepath.Join(rootDir, "mnt", "stateful_partition", "etc"),
		filepath.Join(rootDir, "etc", "docker", "key.json"),
		filepath.Join(rootDir, "var", "lib", "systemd", "random-seed"),
	} {
		if err := os.RemoveAll(f); err != nil && !os.IsNotExist(err) {
			return err
		}
	}
	// Directories to remove contents of (but not the directory itself)
	if err := cleanupDir(filepath.Join(rootDir, "var", "cache"), []string{"apt", "debconf"}); err != nil {
		return err
	}
	if err := cleanupDir(filepath.Join(rootDir, "var", "lib", "systemd"), []string{"deb-systemd-helper-enabled"}); err != nil {
		return err
	}
	for _, d := range []string{
		filepath.Join(rootDir, "var", "tmp"),
		filepath.Join(rootDir, "var", "lib", "crash_reporter"),
		filepath.Join(rootDir, "var", "lib", "metrics"),
		filepath.Join(rootDir, "var", "lib", "update_engine"),
		filepath.Join(rootDir, "var", "lib", "whitelist"),
		filepath.Join(rootDir, "var", "lib", "cloud"),
		filepath.Join(rootDir, "var", "log", "journal"),
		filepath.Join(rootDir, "var", "log", "audit"),
		filepath.Join(rootDir, "etc", "netplan"),
		filepath.Join(rootDir, "tmp"),
	} {
		if err := cleanupDir(d, nil); err != nil {
			return err
		}
	}
	// There are a few files in /var/log that need to exist for daemons to work.
	// The best way to clear logs is to zero them out instead of deleting them.
	if err := zeroAllFiles(filepath.Join(rootDir, "var", "log")); err != nil {
		return err
	}
	// /etc/ssh needs some special handling
	if err := cleanEtcSSH(rootDir); err != nil {
		return err
	}
	log.Println("Done cleaning up machine state")
	return nil
}

func executeSteps(ctx context.Context, s *state, deps stepDeps) error {
	for i, step := range s.data.Config.Steps {
		// In the case where executeSteps runs after a reboot, we need to skip
		// through all the steps that have already been completed.
		if i < s.data.CurrentStep {
			continue
		}
		abstractStep, err := parseStep(step.Type, step.Args)
		if err != nil {
			return fmt.Errorf("error parsing step %d: %v", i, err)
		}
		if err := abstractStep.run(ctx, s, &deps); err != nil {
			return fmt.Errorf("error in step %d: %v", i, err)
		}
		// Persist our most recent completed step to disk, so we can resume after a reboot.
		s.data.CurrentStep++
		if err := s.write(); err != nil {
			return err
		}
	}
	return nil
}

// Deps contains provisioner service dependencies.
type Deps struct {
	// GCSClient is used to access Google Cloud Storage.
	GCSClient *storage.Client
	// TarCmd is used for tar.
	TarCmd string
	// SystemctlCmd is used to access systemd.
	SystemctlCmd string
	// RootdevCmd is the path to the rootdev binary.
	RootdevCmd string
	// CgptCmd is the path to the cgpt binary.
	CgptCmd string
	// Resize2fsCmd is the path to the resize2fs binary.
	Resize2fsCmd string
	// E2fsckCmd is the path to the e2fsck binary.
	E2fsckCmd string
	// RootDir is the path to the root file system. Should be "/" in all real
	// runtime situations.
	RootDir string
	// DockerCredentialGCR is a path to a docker-credential-gcr program to use as a Docker
	// credential helper.
	DockerCredentialGCR string
	// VeritySetupImage is a path to a file system tarball (which can be imported
	// as a Docker image) that contains the "veritysetup" tool.
	VeritySetupImage string
	// HandleDiskLayoutBin is a path to a program for reformatting a COS disk
	// image.
	HandleDiskLayoutBin string
}

func run(ctx context.Context, deps Deps, runState *state) (err error) {
	systemd := &systemdClient{systemctl: deps.SystemctlCmd}
	if err := repartitionBootDisk(deps, runState); err != nil {
		return err
	}
	if err := setup(runState, deps, systemd); err != nil {
		return err
	}
	stepDeps := stepDeps{
		GCSClient:        deps.GCSClient,
		VeritySetupImage: deps.VeritySetupImage,
	}
	if err := executeSteps(ctx, runState, stepDeps); err != nil {
		return err
	}
	if err := stopServices(systemd); err != nil {
		return fmt.Errorf("error stopping services: %v", err)
	}
	if err := cleanup(deps.RootDir, runState.dir); err != nil {
		return fmt.Errorf("error in cleanup: %v", err)
	}
	log.Println("Done provisioning machine")
	return nil
}

// Run runs a full provisioning flow based on the provided config. The stateDir
// is used for persisting data used as part of provisioning. The stateDir allows
// the provisioning flow to be interrupted (e.g. by a reboot) and resumed.
func Run(ctx context.Context, deps Deps, stateDir string, c Config) error {
	log.Println("Provisioning machine...")
	runState, err := initState(ctx, deps, stateDir, c)
	if err != nil {
		return err
	}
	return run(ctx, deps, runState)
}

// Resume resumes provisioning from the state provided at stateDir.
func Resume(ctx context.Context, deps Deps, stateDir string) (err error) {
	log.Println("Resuming provisioning...")
	runState, err := loadState(stateDir)
	if err != nil {
		return err
	}
	return run(ctx, deps, runState)
}
