package main

import (
	"flag"
	"io"
	"log"
	"os"
	"path"
	"sort"
	"strings"

	"github.com/cavaliergopher/cpio"
	"github.com/pierrec/lz4/v4"
	"golang.org/x/sys/unix"

	"source.monogon.dev/metropolis/node/build/fsspec"
)

var (
	outPath = flag.String("out", "", "Output file path")
)

type placeEnum int

const (
	// placeNone implies that currently nothing is placed at that path.
	// Can be overridden by everything.
	placeNone placeEnum = 0
	// placeDirImplicit means that there is currently a implied directory
	// at the given path. It can be overridden by (and only by) an explicit
	// directory.
	placeDirImplicit placeEnum = 1
	// placeDirExplicit means that there is an explicit (i.e. specified by
	// the FSSpec) directory at the given path. Nothing else can override
	// this.
	placeDirExplicit placeEnum = 2
	// placeNonDir means that there is a file-type resource (i.e a file, symlink
	// or special_file) at the given path. Nothing else can override this.
	placeNonDir placeEnum = 3
)

// place represents the state a given canonical path is in during metadata
// construction. Its zero value is { State: placeNone, Inode: nil }.
type place struct {
	State placeEnum
	// Inode contains one of the types inside an FSSpec (e.g. *fsspec.File)
	Inode interface{}
}

// Usage: -out <out-path.cpio.lz4> fsspec-path...
func main() {
	flag.Parse()
	outFile, err := os.Create(*outPath)
	if err != nil {
		log.Fatalf("Failed to open CPIO output file: %v", err)
	}
	defer outFile.Close()
	compressedOut := lz4.NewWriter(outFile)
	compressedOut.Apply(lz4.LegacyOption(true))
	defer compressedOut.Close()
	cpioWriter := cpio.NewWriter(compressedOut)
	defer cpioWriter.Close()

	spec, err := fsspec.ReadMergeSpecs(flag.Args())
	if err != nil {
		log.Fatalf("failed to load specs: %v", err)
	}

	// Map of paths to metadata for validation & implicit directory injection
	places := make(map[string]place)

	// The idea behind this machinery is that we try to place all files and
	// directories into a map while creating the required parent directories
	// on-the-fly as implicit directories. Overriding an implicit directory
	// with an explicit one is allowed thus the actual order in which this
	// structure is created does not matter. All non-directories cannot be
	// overridden anyways so their insertion order does not matter.
	// This also has the job of validating the FSSpec structure, ensuring that
	// there are no duplicate paths and that there is nothing placed below a
	// non-directory.
	var placeInode func(p string, isDir bool, inode interface{})
	placeInode = func(p string, isDir bool, inode interface{}) {
		cleanPath := path.Clean(p)
		if !isDir {
			if places[cleanPath].State != placeNone {
				log.Fatalf("Invalid FSSpec: Duplicate Inode at %q", cleanPath)
			}
			places[cleanPath] = place{
				State: placeNonDir,
				Inode: inode,
			}
		} else {
			switch places[cleanPath].State {
			case placeNone:
				if inode != nil {
					places[cleanPath] = place{
						State: placeDirExplicit,
						Inode: inode,
					}
				} else {
					places[cleanPath] = place{
						State: placeDirImplicit,
						Inode: &fsspec.Directory{Path: cleanPath, Mode: 0555},
					}
				}
			case placeDirImplicit:
				if inode != nil {
					places[cleanPath] = place{
						State: placeDirExplicit,
						Inode: inode,
					}
				}
			case placeDirExplicit:
				if inode != nil {
					log.Fatalf("Invalid FSSpec: Conflicting explicit directories at %v", cleanPath)
				}
			case placeNonDir:
				log.Fatalf("Invalid FSSpec: Trying to place inode below non-directory at #{cleanPath}")
			default:
				panic("unhandled placeEnum value")
			}
		}
		parentPath, _ := path.Split(p)
		parentPath = path.Clean(parentPath)
		if parentPath == "/" || parentPath == p {
			return
		}
		placeInode(parentPath, true, nil)
	}
	for _, d := range spec.Directory {
		placeInode(d.Path, true, d)
	}
	for _, f := range spec.File {
		placeInode(f.Path, false, f)
	}
	for _, s := range spec.SymbolicLink {
		placeInode(s.Path, false, s)
	}
	for _, s := range spec.SpecialFile {
		placeInode(s.Path, false, s)
	}

	var writeOrder []string
	for path := range places {
		writeOrder = append(writeOrder, path)
	}
	// Sorting a list of normalized paths representing a tree gives us Depth-
	// first search (DFS) order which is the correct order for writing archives.
	// This also makes the output reproducible.
	sort.Strings(writeOrder)

	for _, path := range writeOrder {
		place := places[path]
		switch i := place.Inode.(type) {
		case *fsspec.File:
			inF, err := os.Open(i.SourcePath)
			if err != nil {
				log.Fatalf("Failed to open source path for file %q: %v", i.Path, err)
			}
			inFStat, err := inF.Stat()
			if err != nil {
				log.Fatalf("Failed to stat source path for file %q: %v", i.Path, err)
			}
			if err := cpioWriter.WriteHeader(&cpio.Header{
				Mode: cpio.FileMode(i.Mode),
				Name: strings.TrimPrefix(i.Path, "/"),
				Size: inFStat.Size(),
			}); err != nil {
				log.Fatalf("Failed to write cpio header for file %q: %v", i.Path, err)
			}
			if _, err := io.Copy(cpioWriter, inF); err != nil {
				log.Fatalf("Failed to copy file %q into cpio: %v", i.SourcePath, err)
			}
			inF.Close()
		case *fsspec.Directory:
			if err := cpioWriter.WriteHeader(&cpio.Header{
				Mode: cpio.FileMode(i.Mode) | cpio.TypeDir,
				Name: strings.TrimPrefix(i.Path, "/"),
			}); err != nil {
				log.Fatalf("Failed to write cpio header for directory %q: %v", i.Path, err)
			}
		case *fsspec.SymbolicLink:
			if err := cpioWriter.WriteHeader(&cpio.Header{
				// Symlinks are 0777 by definition (from man 7 symlink on Linux)
				Mode: 0777 | cpio.TypeSymlink,
				Name: strings.TrimPrefix(i.Path, "/"),
				Size: int64(len(i.TargetPath)),
			}); err != nil {
				log.Fatalf("Failed to write cpio header for symlink %q: %v", i.Path, err)
			}
			if _, err := cpioWriter.Write([]byte(i.TargetPath)); err != nil {
				log.Fatalf("Failed to write cpio symlink %q: %v", i.Path, err)
			}
		case *fsspec.SpecialFile:
			mode := cpio.FileMode(i.Mode)
			switch i.Type {
			case fsspec.SpecialFile_CHARACTER_DEV:
				mode |= cpio.TypeChar
			case fsspec.SpecialFile_BLOCK_DEV:
				mode |= cpio.TypeBlock
			case fsspec.SpecialFile_FIFO:
				mode |= cpio.TypeFifo
			}

			if err := cpioWriter.WriteHeader(&cpio.Header{
				Mode:     mode,
				Name:     strings.TrimPrefix(i.Path, "/"),
				DeviceID: int(unix.Mkdev(i.Major, i.Minor)),
			}); err != nil {
				log.Fatalf("Failed to write CPIO header for special file %q: %v", i.Path, err)
			}
		default:
			panic("inode type not handled")
		}
	}
}
