///bin/true ; exec /usr/bin/env go run "$0" "$@"
// 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 (
	"archive/tar"
	"bufio"
	"compress/gzip"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
)

var output = flag.String("output", "", "Path to the generated tarball")
var manifest = flag.String("manifest", "", "Path to the file containing a description of the tarball's contents")

func archiveFile(tw *tar.Writer, src, dest string) error {
	file, err := os.Open(src)
	if err != nil {
		return err
	}
	defer file.Close()
	info, err := file.Stat()
	if err != nil {
		return err
	}

	hdr, err := tar.FileInfoHeader(info, info.Name())
	if err != nil {
		return err
	}
	hdr.Name = dest
	hdr.Uid = 0
	hdr.Gid = 0
	if err := tw.WriteHeader(hdr); err != nil {
		return err
	}
	_, err = io.Copy(tw, file)
	return err
}

func archiveDirectory(tw *tar.Writer, src, dest string) error {
	return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		fileDest := filepath.Join(dest, path[len(src)+1:])
		return archiveFile(tw, path, fileDest)
	})
}

func createTar(archive string, mappings map[string]string) error {
	file, err := os.Create(archive)
	if err != nil {
		return err
	}
	defer file.Close()

	gw := gzip.NewWriter(file)
	defer gw.Close()
	tw := tar.NewWriter(gw)
	defer tw.Close()

	for dest, src := range mappings {
		info, err := os.Stat(src)
		if err != nil {
			return err
		}
		if info.IsDir() {
			err = archiveDirectory(tw, src, dest)
		} else {
			err = archiveFile(tw, src, dest)
		}
		if err != nil {
			return err
		}
	}

	return nil
}

func readManifest(manifest string) (map[string]string, error) {
	file, err := os.Open(manifest)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	result := make(map[string]string)

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		parts := strings.SplitN(scanner.Text(), "=", 2)
		result[parts[0]] = parts[1]
	}

	if err := scanner.Err(); err != nil {
		return nil, err
	}

	return result, nil
}

func generateArchive(manifest string, output string) error {
	if _, err := os.Stat(output); err == nil {
		// The file exists, need to remove it first.
		if err := os.Remove(output); err != nil {
			return err
		}
	}
	mappings, err := readManifest(manifest)
	if err != nil {
		return err
	}
	return createTar(output, mappings)
}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, `Usage: tar_maker --manifest path/to/manifest

This tool creates a tarball whose contents are described in a file manifest.
Each line in the manifest should be of the form:
    <path in tarball>=<path to source file or dir>

The tarball is compressed using gzip.
`)
		flag.PrintDefaults()
	}
	flag.Parse()

	if *output == "" {
		flag.Usage()
		log.Fatalf("Error: missing -output flag.")
	}
	if *manifest == "" {
		flag.Usage()
		log.Fatalf("Error: missing -manifest flag.")
	}

	if err := generateArchive(*manifest, *output); err != nil {
		log.Fatalf("Error: unable to create archive %s: %v", *output, err)
	}
}
