// Copyright 2017 The Fuchsia 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 main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"

	"go.fuchsia.dev/fuchsia/garnet/go/src/thinfs/block/file"
	"go.fuchsia.dev/fuchsia/garnet/go/src/thinfs/fs"
	"go.fuchsia.dev/fuchsia/garnet/go/src/thinfs/fs/msdosfs"
	"go.fuchsia.dev/fuchsia/garnet/go/src/thinfs/fs/msdosfs/clock"
)

var (
	mkfs          = flag.String("mkfs", "", "Path to mkfs-msdosfs host tool from Zircon")
	target        = flag.String("output", "", "Target file/disk to write EFI partition to")
	size          = flag.Uint64("size", 0, "(optional) Size of partition to create")
	offset        = flag.Uint64("offset", 0, "(optional) Offset into target to write partition to")
	zircon        = flag.String("zircon", "", "(optional) Path to source file for zircon.bin")
	bootdata      = flag.String("bootdata", "", "(optional) Path to source file for bootdata.bin")
	efiBootloader = flag.String("efi-bootloader", "", "(optional) Path to source file for EFI/BOOT/BOOTX64.EFI")
	manifest      = flag.String("manifest", "", "(optional) Path to a manifest file of the form `dst=src\n` to import to partition")
	zedboot       = flag.String("zedboot", "", "(optional) Path to a source file for zedboot.bin")
	cmdline       = flag.String("cmdline", "", "(optional) Bootloader cmdline file")
	timestamp     = flag.Int64("timestamp", -1, "(optional) Unix timestamp in seconds used to "+
		"create all files. The actual timestamp used may be different due to FAT32's limit time "+
		"granularity")
)

// minSize is the minimum image size, as the tool currently always builds fat32.
const minSize = 63 * 1024 * 1024

// Fudge factor (percentage) to account for filesystem metadata.
const fudgeFactor = 5

type fixedClock struct {
	now time.Time
}

func (c *fixedClock) Now() time.Time {
	return c.now
}

func main() {
	flag.Parse()

	if *target == "" || *mkfs == "" {
		flag.CommandLine.Usage()
		fmt.Printf("\nerror: -target and -mkfs are required\n")
		os.Exit(1)
	}

	var err error
	*mkfs, err = filepath.Abs(*mkfs)
	if err != nil {
		log.Fatal(err)
	}
	*target, err = filepath.Abs(*target)
	if err != nil {
		log.Fatal(err)
	}

	// Slurp up all the copies to do, as it will make the final copy code simpler.
	// It can also be used to compute the size if the size was not given.
	dstSrc := map[string]string{}
	if *zircon != "" {
		dstSrc["zircon.bin"] = *zircon
	}
	if *bootdata != "" {
		dstSrc["bootdata.bin"] = *bootdata
	}
	if *efiBootloader != "" {
		dstSrc["EFI/BOOT/BOOTX64.EFI"] = *efiBootloader

		tf, err := ioutil.TempFile("", "gsetup-boot")
		if err != nil {
			log.Fatal(err)
		}
		tf.WriteString("efi\\boot\\bootx64.efi")
		tf.Close()
		defer os.Remove(tf.Name())
		dstSrc["EFI/Google/GSetup/Boot"] = tf.Name()
	}
	if *zedboot != "" {
		dstSrc["zedboot.bin"] = *zedboot
	}
	if *cmdline != "" {
		dstSrc["cmdline"] = *cmdline
	}
	if *manifest != "" {
		r, err := newManifestReader(*manifest)
		if err != nil {
			log.Fatal(err)
		}
		for {
			dst, src, err := r.Next()
			if dst != "" && src != "" {
				dstSrc[dst] = src
			}
			if err == io.EOF {
				break
			}
			if err != nil {
				log.Fatal(err)
			}
		}
		r.Close()
	}

	if *size == 0 {
		*size = computeSize(dstSrc)
	}
	*size = alignSize(*size)

	if *timestamp >= 0 {
		now := time.Unix(*timestamp, 0)

		// FAT32 starts at 1980-01-01 to 2107-12-31, so clamp to that range.
		if now.Year() < 1980 {
			now = time.Date(1980, 1, 1, 0, 0, 0, 0, time.Local)
		} else if now.Year() > 2107 {
			now = time.Date(2107, 12, 31, 23, 59, 58, 0, time.Local)
		}

		// FAT stores modification time at 2s granularity
		now = now.Truncate(time.Second * 2)

		clock.Now = func() time.Time {
			return now
		}
	}

	f, err := os.Create(*target)
	if err != nil {
		log.Fatal(err)
	}
	f.Close()

	args := []string{*mkfs,
		"-@", strconv.FormatUint(*offset, 10),
		"-S", strconv.FormatUint(*size, 10),
		"-F", "32",
		"-L", "ESP",
		"-O", "Fuchsia",
		"-b", "512",
	}

	if *timestamp >= 0 {
		args = append(args, "-T", strconv.FormatInt(*timestamp, 10))
	}

	args = append(args, *target)

	cmd := exec.Command(args[0], args[1:]...)
	output, err := cmd.CombinedOutput()
	if err != nil {
		os.Stderr.Write(output)
		log.Fatalf("mkfs did not succceed, see output above.\n%s\n", strings.Join(args, " "))
	}

	f, err = os.OpenFile(*target, os.O_RDWR|os.O_CREATE, 0644)
	if err != nil {
		log.Fatal(err)
	}
	dev, err := file.NewRange(f, 512, int64(*offset), int64(*size))
	if err != nil {
		log.Fatal(err)
	}

	fatfs, err := msdosfs.New(*target, dev, fs.ReadWrite|fs.Force)
	if err != nil {
		log.Fatal(err)
	}

	// Sort the files we are going to copy to make sure the EFI partition
	// is reproducible.
	var dsts []string
	for dst := range dstSrc {
		dsts = append(dsts, dst)
	}
	sort.Strings(dsts)

	root := fatfs.RootDirectory()
	for _, dst := range dsts {
		msCopyIn(root, dstSrc[dst], dst)
	}

	root.Sync()
	if err := root.Close(); err != nil {
		log.Fatal(err)
	}
	if err := fatfs.Close(); err != nil {
		log.Fatal(err)
	}
	f.Sync()
	if err := f.Close(); err != nil {
		log.Fatal(err)
	}
}

// msCopyIn copies src from the host filesystem into dst under the given
// msdosfs root.
func msCopyIn(root fs.Directory, src, dst string) {
	d := root
	defer d.Sync()

	dStack := []fs.Directory{}

	defer func() {
		for _, d := range dStack {
			d.Sync()
			d.Close()
		}
	}()

	destdir := filepath.Dir(dst)
	name := filepath.Base(dst)

	for _, part := range strings.Split(destdir, "/") {
		if part == "." {
			continue
		}

		var err error
		_, d, _, err = d.Open(part, fs.OpenFlagRead|fs.OpenFlagCreate|fs.OpenFlagDirectory)
		if err != nil {
			log.Fatalf("open/create %s: %#v %s", part, err, err)
		}
		d.Sync()
		dStack = append(dStack, d)
	}

	to, _, _, err := d.Open(name, fs.OpenFlagWrite|fs.OpenFlagCreate|fs.OpenFlagFile)
	if err != nil {
		log.Fatalf("creating %s in msdosfs: %s", name, err)
	}
	defer to.Close()

	from, err := os.Open(src)
	if err != nil {
		log.Fatal(err)
	}
	defer from.Close()

	b := make([]byte, 4096)
	for err == nil {
		var n int
		n, err = from.Read(b)
		if n > 0 {
			if _, err := to.Write(b[:n], 0, fs.WhenceFromCurrent); err != nil {
				log.Fatalf("writing %s to msdosfs file: %s", name, err)
			}
		}
	}
	to.Sync()
	if err != nil && err != io.EOF {
		log.Fatal(err)
	}
}

func getSize(f string) uint64 {
	if f == "" {
		return 0
	}
	fi, err := os.Stat(f)
	if err != nil {
		log.Fatal(err)
	}
	return uint64(fi.Size())
}

type manifestReader struct {
	*os.File
	*bufio.Reader
	manifestRoot string
}

func newManifestReader(path string) (*manifestReader, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	return &manifestReader{
		f,
		bufio.NewReader(f),
		filepath.Dir(path),
	}, nil
}

func (r *manifestReader) Next() (dst, src string, err error) {
	for err == nil {
		line, err := r.ReadString('\n')
		line = strings.TrimSpace(line)
		if strings.HasPrefix(line, "#") {
			continue
		}
		parts := strings.SplitN(line, "=", 2)
		if len(parts) != 2 {
			log.Printf("make-efi: bad manifest line format: %q, skipping", line)
			continue
		}
		return parts[0], filepath.Join(r.manifestRoot, parts[1]), err
	}
	return "", "", err
}

func computeSize(dstSrc map[string]string) uint64 {
	var total uint64
	for _, src := range dstSrc {
		total += getSize(src)
	}
	total += total * 100 / fudgeFactor
	pad := total % 63
	if pad != 0 {
		total += pad
	}
	if total < minSize {
		return minSize
	}

	return total
}

// sectors per track is 63, and a sector is 512, so we must round to the nearest
// 32256.
const sizeAlignment = 32256

func alignSize(total uint64) uint64 {
	if d := total % sizeAlignment; d != 0 {
		total = total + (sizeAlignment - d)
	}
	return total
}
