// Copyright 2014 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Mkzip creates a zip file from a 'proto' file describing the contents.
//
// The proto file is inspired by the Plan 9 mkfs prototype file format.
// It describes a file tree, one directory per line, with leading tab
// indentation marking the tree structure. Each line contains a leading
// name field giving the name of the file to copy into the zip file,
// and then a sequence of optional key=value attributes to control
// the copy. The only known attribute is src=foo, meaning copy the
// actual data for the file (or directory) from an alternate location.
package main

import (
	"archive/zip"
	"bufio"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"strings"
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: mkzip [-r root] src.proto out.zip\n")
	os.Exit(2)
}

func sysfatal(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "mkzip: %s\n", fmt.Sprintf(format, args...))
	os.Exit(2)
}

var (
	root      = flag.String("r", ".", "interpret source paths relative to this directory")
	gopackage = flag.String("p", "", "write Go source file in this package")
)

type stack struct {
	name  string
	src   string
	depth int
}

func main() {
	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	args := flag.Args()
	if len(args) != 2 {
		usage()
	}

	rf, err := os.Open(args[0])
	if err != nil {
		sysfatal("%v", err)
	}
	r := bufio.NewScanner(rf)

	zf, err := os.Create(args[1])
	if err != nil {
		sysfatal("%v", err)
	}

	var w io.Writer = zf
	if *gopackage != "" {
		fmt.Fprintf(zf, "package %s\n\nfunc init() {\n\tunzip(\"", *gopackage)
		gw := &goWriter{b: bufio.NewWriter(w)}
		defer func() {
			if err := gw.Close(); err != nil {
				sysfatal("finishing Go output: %v", err)
			}
		}()
		w = gw
	}
	z := zip.NewWriter(w)

	lineno := 0

	addfile := func(info os.FileInfo, dst string, src string) {
		zh, err := zip.FileInfoHeader(info)
		if err != nil {
			sysfatal("%s:%d: %s: %v", args[0], lineno, src, err)
		}
		zh.Name = dst
		zh.Method = zip.Deflate
		if info.IsDir() && !strings.HasSuffix(dst, "/") {
			zh.Name += "/"
		}
		w, err := z.CreateHeader(zh)
		if err != nil {
			sysfatal("%s:%d: %s: %v", args[0], lineno, src, err)
		}
		if info.IsDir() {
			return
		}
		r, err := os.Open(src)
		if err != nil {
			sysfatal("%s:%d: %s: %v", args[0], lineno, src, err)
		}
		defer r.Close()
		if _, err := io.Copy(w, r); err != nil {
			sysfatal("%s:%d: %s: %v", args[0], lineno, src, err)
		}
	}

	var stk []stack

	for r.Scan() {
		line := r.Text()
		lineno++
		s := strings.TrimLeft(line, "\t")
		prefix, line := line[:len(line)-len(s)], s
		if i := strings.Index(line, "#"); i >= 0 {
			line = line[:i]
		}
		f := strings.Fields(line)
		if len(f) == 0 {
			continue
		}
		if strings.HasPrefix(line, " ") {
			sysfatal("%s:%d: must use tabs for indentation", args[0], lineno)
		}
		depth := len(prefix)
		for len(stk) > 0 && depth <= stk[len(stk)-1].depth {
			stk = stk[:len(stk)-1]
		}
		parent := ""
		psrc := *root
		if len(stk) > 0 {
			parent = stk[len(stk)-1].name
			psrc = stk[len(stk)-1].src
		}
		if strings.Contains(f[0], "/") {
			sysfatal("%s:%d: destination name cannot contain slash", args[0], lineno)
		}
		name := path.Join(parent, f[0])
		src := filepath.Join(psrc, f[0])
		for _, attr := range f[1:] {
			i := strings.Index(attr, "=")
			if i < 0 {
				sysfatal("%s:%d: malformed attribute %q", args[0], lineno, attr)
			}
			key, val := attr[:i], attr[i+1:]
			switch key {
			case "src":
				src = val
			default:
				sysfatal("%s:%d: unknown attribute %q", args[0], lineno, attr)
			}
		}

		stk = append(stk, stack{name: name, src: src, depth: depth})

		if f[0] == "*" || f[0] == "+" {
			if f[0] == "*" {
				dir, err := ioutil.ReadDir(psrc)
				if err != nil {
					sysfatal("%s:%d: %v", args[0], lineno, err)
				}
				for _, d := range dir {
					addfile(d, path.Join(parent, d.Name()), filepath.Join(psrc, d.Name()))
				}
			} else {
				err := filepath.Walk(psrc, func(src string, info os.FileInfo, err error) error {
					if err != nil {
						return err
					}
					if src == psrc {
						return nil
					}
					if psrc == "." {
						psrc = ""
					}
					name := path.Join(parent, filepath.ToSlash(src[len(psrc):]))
					addfile(info, name, src)
					return nil
				})
				if err != nil {
					sysfatal("%s:%d: %v", args[0], lineno, err)
				}
			}
			continue
		}

		fi, err := os.Stat(src)
		if err != nil {
			sysfatal("%s:%d: %v", args[0], lineno, err)
		}
		addfile(fi, name, src)
	}

	if err := z.Close(); err != nil {
		sysfatal("finishing zip file: %v", err)
	}
}

type goWriter struct {
	b *bufio.Writer
}

func (w *goWriter) Write(b []byte) (int, error) {
	for _, c := range b {
		fmt.Fprintf(w.b, "\\x%02x", c)
	}
	return len(b), nil
}

func (w *goWriter) Close() error {
	fmt.Fprintf(w.b, "\")\n}\n")
	w.b.Flush()
	return nil
}
