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

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"golang.org/x/sys/unix"

	"cos.googlesource.com/cos/tools.git/src/pkg/tools/partutil"
	"cos.googlesource.com/cos/tools.git/src/pkg/utils"
)

func switchRoot(deps Deps, runState *state) (err error) {
	if !runState.data.Config.BootDisk.ReclaimSDA3 {
		log.Println("ReclaimSDA3 is not set, not switching root device")
		return nil
	}
	bootDev, err := partutil.BootDev(deps.RootdevCmd)
	if err != nil {
		return err
	}
	sda3Device := bootDev + "3"
	sda5Device := bootDev + "5"
	rootDev, err := exec.Command(deps.RootdevCmd, "-s").Output()
	if err != nil {
		if exitErr, ok := err.(*exec.ExitError); ok {
			return fmt.Errorf("error running rootdev: %v: stderr = %q", exitErr, string(exitErr.Stderr))
		}
		return fmt.Errorf("error running rootdev: %v", err)
	}
	rootDevStr := strings.TrimSpace(string(rootDev))
	if rootDevStr == sda5Device {
		log.Printf("Current root device is %q, not switching root device", rootDevStr)
		return nil
	}
	log.Println("Need to switch root device")
	log.Println("Copying partition 3 to partition 5...")
	in, err := os.Open(sda3Device)
	if err != nil {
		return err
	}
	defer utils.CheckClose(in, fmt.Sprintf("error closing %q", sda3Device), &err)
	out, err := os.Create(sda5Device)
	if err != nil {
		return err
	}
	defer utils.CheckClose(out, fmt.Sprintf("error closing %q", sda5Device), &err)
	if _, err := io.Copy(out, in); err != nil {
		return fmt.Errorf("error copying from %q to %q: %v", sda3Device, sda5Device, err)
	}
	log.Println("Setting GPT priority...")
	if err := utils.RunCommand([]string{deps.CgptCmd, "prioritize", "-P", "5", "-i", "4", bootDev}, "", nil); err != nil {
		return err
	}
	log.Println("Reboot required to switch root device")
	return ErrRebootRequired
}

func shrinkSDA3(deps Deps, runState *state) error {
	if !runState.data.Config.BootDisk.ReclaimSDA3 {
		log.Println("ReclaimSDA3 is not set, not shrinking partition 3")
		return nil
	}
	bootDev, err := partutil.BootDev(deps.RootdevCmd)
	if err != nil {
		return err
	}
	minimal, err := partutil.IsPartitionMinimal(bootDev, 3)
	if err != nil {
		return fmt.Errorf("error checking partition 3 size: %v", err)
	}
	if minimal {
		log.Println("partition 3 is minimally sized, not shrinking partition 3")
		return nil
	}
	log.Println("ReclaimSDA3 is set, and partition 3 is not minimal; now shrinking partition 3")
	if _, err := partutil.MinimizePartition(bootDev, 3); err != nil {
		return fmt.Errorf("error minimizing partition 3: %v", err)
	}
	log.Println("Reboot required to reload partition table changes")
	return ErrRebootRequired
}

func setupOnShutdownUnit(deps Deps, runState *state) (err error) {
	if err := mountFunc("", filepath.Join(deps.RootDir, "tmp"), "", unix.MS_REMOUNT|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
		return fmt.Errorf("error remounting /tmp as exec: %v", err)
	}
	out := filepath.Join(deps.RootDir, "tmp", "handle_disk_layout.bin")
	if err := utils.CopyFile(deps.HandleDiskLayoutBin, out); err != nil {
		return err
	}
	if err := os.Chmod(out, 755); err != nil {
		return err
	}
	bootDev, err := partutil.BootDev(deps.RootdevCmd)
	if err != nil {
		return err
	}
	data := fmt.Sprintf(`[Unit]
Description=Run after everything unmounted
DefaultDependencies=false
Conflicts=shutdown.target
Before=mnt-stateful_partition.mount usr-share-oem.mount
After=tmp.mount

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/bin/bash -c '/tmp/handle_disk_layout.bin %s 1 8 "%s" "%t" 2>&1 | sed "s/^/BuildStatus: /"'
TimeoutStopSec=600
StandardOutput=tty
StandardError=tty
TTYPath=/dev/ttyS2
`, bootDev, runState.data.Config.BootDisk.OEMSize, runState.data.Config.BootDisk.ReclaimSDA3)
	if err := ioutil.WriteFile(filepath.Join(deps.RootDir, "etc/systemd/system/last-run.service"), []byte(data), 0664); err != nil {
		return err
	}
	systemd := systemdClient{systemctl: deps.SystemctlCmd}
	if err := systemd.start("last-run.service", []string{"--no-block"}); err != nil {
		return err
	}
	// journald needs to be stopped in order for the stateful partition to be
	// unmounted at shutdown. We need the stateful partition to be unmounted so
	// that disk repartitioning can occur.
	if err := systemd.stopJournald(deps.RootDir); err != nil {
		return err
	}
	return nil
}

func calcSDA3End(device string) (uint64, error) {
	sda3Start, err := partutil.ReadPartitionStart(device, 3)
	if err != nil {
		return 0, err
	}
	sda3Size, err := partutil.ReadPartitionSize(device, 3)
	if err != nil {
		return 0, err
	}
	sda3End := sda3Start + sda3Size - 1
	return sda3End, nil
}

func waitForDiskResize(deps Deps, runState *state) error {
	if !runState.data.Config.BootDisk.WaitForDiskResize {
		log.Println("WaitForDiskResize is not set, not waiting for a boot disk resize")
		return nil
	}
	if runState.data.DiskResizeComplete {
		log.Println("Already finished waiting for disk resize, not waiting again")
		return nil
	}
	bootDev, err := partutil.BootDev(deps.RootdevCmd)
	if err != nil {
		return err
	}
	startSize, err := ioutil.ReadFile(filepath.Join(deps.RootDir, fmt.Sprintf("sys/class/block/%s/size", filepath.Base(bootDev))))
	if err != nil {
		return err
	}
	log.Println("WaitForDiskResize is set; waiting for the boot disk size to change. Timeout is 3 minutes")
	start := time.Now()
	end := start.Add(3 * time.Minute)
	for time.Now().Before(end) {
		curSize, err := ioutil.ReadFile(filepath.Join(deps.RootDir, fmt.Sprintf("sys/class/block/%s/size", filepath.Base(bootDev))))
		if err != nil {
			return err
		}
		if string(curSize) != string(startSize) {
			log.Printf("Boot disk size has changed: start %q, end %q", strings.TrimSpace(string(startSize)), strings.TrimSpace(string(curSize)))
			runState.data.DiskResizeComplete = true
			return runState.write()
		}
		time.Sleep(time.Second)
	}
	return errors.New("timed out waiting for disk resize")
}

func relocatePartitions(deps Deps, runState *state) error {
	if !runState.data.Config.BootDisk.ReclaimSDA3 && runState.data.Config.BootDisk.OEMSize == "" {
		log.Println("ReclaimSDA3 is not set, OEM resize not requested, not relocating partitions")
		return nil
	}
	bootDev, err := partutil.BootDev(deps.RootdevCmd)
	if err != nil {
		return err
	}
	if runState.data.Config.BootDisk.OEMSize != "" {
		// Check if OEM partition is after sda3; if so, then we're done
		oemStart, err := partutil.ReadPartitionStart(bootDev, 8)
		if err != nil {
			return err
		}
		sda3End, err := calcSDA3End(bootDev)
		if err != nil {
			return err
		}
		if oemStart > sda3End {
			log.Println("OEM resize requested, OEM appears to be relocated after sda3. Partition relocation is complete")
			return nil
		}
	} else {
		// Check two things:
		// 1. sda3 is minimal
		// 2. Stateful partition is located immediately after sda3
		//
		// If both are true, we are done.
		minimal, err := partutil.IsPartitionMinimal(bootDev, 3)
		if err != nil {
			return err
		}
		statefulStart, err := partutil.ReadPartitionStart(bootDev, 1)
		if err != nil {
			return err
		}
		sda3Start, err := partutil.ReadPartitionStart(bootDev, 3)
		// The stateful partition is relocated 4096 sectors after the start of sda3.
		// See src/pkg/tools/handle_disk_layout.go for details.
		if minimal && statefulStart == sda3Start+4096 {
			log.Println("ReclaimSDA3 is set, sda3 appears to have been reclaimed. Partition relocation is complete")
			return nil
		}
	}
	// Partition relocation must be done. Prepare for disk relocation to happen on
	// the next reboot
	log.Println("Partition relocation is required. Preparing for partition relocation to occur on the next reboot")
	if err := setupOnShutdownUnit(deps, runState); err != nil {
		return err
	}
	log.Println("Reboot required to relocate partitions")
	return ErrRebootRequired
}

func resizeOEMFileSystem(deps Deps, runState *state) error {
	if !runState.data.Config.BootDisk.ReclaimSDA3 && runState.data.Config.BootDisk.OEMSize == "" {
		log.Println("ReclaimSDA3 is not set, OEM resize not requested, partition relocation did not occur, FS resize unnecessary")
		return nil
	}
	// Check if OEM partition is after sda3; if so, then relocation occurred and
	// we need to resize the file system.
	bootDev, err := partutil.BootDev(deps.RootdevCmd)
	if err != nil {
		return err
	}
	sda3End, err := calcSDA3End(bootDev)
	if err != nil {
		return err
	}
	oemStart, err := partutil.ReadPartitionStart(bootDev, 8)
	if err != nil {
		return err
	}
	if oemStart < sda3End {
		log.Println("OEM partition is before sda3; relocation did not occur, FS resize unnecessary")
		return nil
	}
	log.Println("Partition relocation appears to have occurred, resizing the OEM file system")
	systemd := systemdClient{systemctl: deps.SystemctlCmd}
	if err := systemd.stop("usr-share-oem.mount"); err != nil {
		return err
	}
	sda8Device := bootDev + "8"
	if err := utils.RunCommand([]string{deps.E2fsckCmd, "-fp", sda8Device}, "", nil); err != nil {
		return err
	}
	resizeArgs := []string{deps.Resize2fsCmd, sda8Device}
	if runState.data.Config.BootDisk.OEMFSSize4K != 0 {
		resizeArgs = append(resizeArgs, strconv.FormatUint(runState.data.Config.BootDisk.OEMFSSize4K, 10))
	}
	if err := utils.RunCommand(resizeArgs, "", nil); err != nil {
		return err
	}
	if err := systemd.start("usr-share-oem.mount", nil); err != nil {
		return err
	}
	log.Println("OEM file system resized to account for available space")
	return nil
}

// repartitionBootDisk executes all behaviors related to repartitioning the boot
// disk. Most of these behaviors require a reboot. To keep reboots simple (e.g.
// we don't want to initiate a reboot when deferred statements are unresolved),
// we handle reboots by returning ErrRebootRequired and asking the caller to
// initiate the reboot.
func repartitionBootDisk(deps Deps, runState *state) error {
	if err := switchRoot(deps, runState); err != nil {
		return err
	}
	if err := shrinkSDA3(deps, runState); err != nil {
		return err
	}
	if err := waitForDiskResize(deps, runState); err != nil {
		return err
	}
	if err := relocatePartitions(deps, runState); err != nil {
		return err
	}
	if err := resizeOEMFileSystem(deps, runState); err != nil {
		return err
	}
	return nil
}
