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

package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

/*
The archive format is:

First, on a line by itself
	!<arch>

Then zero or more file records. Each file record has a fixed-size one-line header
followed by data bytes followed by an optional padding byte. The header is:

	%-16s%-12d%-6d%-6d%-8o%-10d`
	name mtime uid gid mode size

(note the trailing backquote). The %-16s here means at most 16 *bytes* of
the name, and if shorter, space padded on the right.
*/

const usageMessage = `Usage: pack op file.a [name....]
Where op is one of cprtx optionally followed by v for verbose output.
For compatibility with old Go build environments the op string grc is
accepted as a synonym for c.

For more information, run
	go doc cmd/pack`

func usage() {
	fmt.Fprintln(os.Stderr, usageMessage)
	os.Exit(2)
}

func main() {
	log.SetFlags(0)
	log.SetPrefix("pack: ")
	// need "pack op archive" at least.
	if len(os.Args) < 3 {
		log.Print("not enough arguments")
		fmt.Fprintln(os.Stderr)
		usage()
	}
	setOp(os.Args[1])
	var ar *Archive
	switch op {
	case 'p':
		ar = archive(os.Args[2], os.O_RDONLY, os.Args[3:])
		ar.scan(ar.printContents)
	case 'r':
		ar = archive(os.Args[2], os.O_RDWR, os.Args[3:])
		ar.scan(ar.skipContents)
		ar.addFiles()
	case 'c':
		ar = archive(os.Args[2], os.O_RDWR|os.O_TRUNC, os.Args[3:])
		ar.addPkgdef()
		ar.addFiles()
	case 't':
		ar = archive(os.Args[2], os.O_RDONLY, os.Args[3:])
		ar.scan(ar.tableOfContents)
	case 'x':
		ar = archive(os.Args[2], os.O_RDONLY, os.Args[3:])
		ar.scan(ar.extractContents)
	default:
		log.Printf("invalid operation %q", os.Args[1])
		fmt.Fprintln(os.Stderr)
		usage()
	}
	if len(ar.files) > 0 {
		log.Fatalf("file %q not in archive", ar.files[0])
	}
}

// The unusual ancestry means the arguments are not Go-standard.
// These variables hold the decoded operation specified by the first argument.
// op holds the operation we are doing (prtx).
// verbose tells whether the 'v' option was specified.
var (
	op      rune
	verbose bool
)

// setOp parses the operation string (first argument).
func setOp(arg string) {
	// Recognize 'go tool pack grc' because that was the
	// formerly canonical way to build a new archive
	// from a set of input files. Accepting it keeps old
	// build systems working with both Go 1.2 and Go 1.3.
	if arg == "grc" {
		arg = "c"
	}

	for _, r := range arg {
		switch r {
		case 'c', 'p', 'r', 't', 'x':
			if op != 0 {
				// At most one can be set.
				usage()
			}
			op = r
		case 'v':
			if verbose {
				// Can be set only once.
				usage()
			}
			verbose = true
		default:
			usage()
		}
	}
}

const (
	arHeader    = "!<arch>\n"
	entryHeader = "%s%-12d%-6d%-6d%-8o%-10d`\n"
	// In entryHeader the first entry, the name, is always printed as 16 bytes right-padded.
	entryLen   = 16 + 12 + 6 + 6 + 8 + 10 + 1 + 1
	timeFormat = "Jan _2 15:04 2006"
)

// An Archive represents an open archive file. It is always scanned sequentially
// from start to end, without backing up.
type Archive struct {
	fd       *os.File // Open file descriptor.
	files    []string // Explicit list of files to be processed.
	pad      int      // Padding bytes required at end of current archive file
	matchAll bool     // match all files in archive
}

// archive opens (and if necessary creates) the named archive.
func archive(name string, mode int, files []string) *Archive {
	// If the file exists, it must be an archive. If it doesn't exist, or if
	// we're doing the c command, indicated by O_TRUNC, truncate the archive.
	if !existingArchive(name) || mode&os.O_TRUNC != 0 {
		create(name)
		mode &^= os.O_TRUNC
	}
	fd, err := os.OpenFile(name, mode, 0)
	if err != nil {
		log.Fatal(err)
	}
	checkHeader(fd)
	return &Archive{
		fd:       fd,
		files:    files,
		matchAll: len(files) == 0,
	}
}

// create creates and initializes an archive that does not exist.
func create(name string) {
	fd, err := os.Create(name)
	if err != nil {
		log.Fatal(err)
	}
	_, err = fmt.Fprint(fd, arHeader)
	if err != nil {
		log.Fatal(err)
	}
	fd.Close()
}

// existingArchive reports whether the file exists and is a valid archive.
// If it exists but is not an archive, existingArchive will exit.
func existingArchive(name string) bool {
	fd, err := os.Open(name)
	if err != nil {
		if os.IsNotExist(err) {
			return false
		}
		log.Fatalf("cannot open file: %s", err)
	}
	checkHeader(fd)
	fd.Close()
	return true
}

// checkHeader verifies the header of the file. It assumes the file
// is positioned at 0 and leaves it positioned at the end of the header.
func checkHeader(fd *os.File) {
	buf := make([]byte, len(arHeader))
	_, err := io.ReadFull(fd, buf)
	if err != nil || string(buf) != arHeader {
		log.Fatalf("%s is not an archive: bad header", fd.Name())
	}
}

// An Entry is the internal representation of the per-file header information of one entry in the archive.
type Entry struct {
	name  string
	mtime int64
	uid   int
	gid   int
	mode  os.FileMode
	size  int64
}

func (e *Entry) String() string {
	return fmt.Sprintf("%s %6d/%-6d %12d %s %s",
		(e.mode & 0777).String(),
		e.uid,
		e.gid,
		e.size,
		time.Unix(e.mtime, 0).Format(timeFormat),
		e.name)
}

// readMetadata reads and parses the metadata for the next entry in the archive.
func (ar *Archive) readMetadata() *Entry {
	buf := make([]byte, entryLen)
	_, err := io.ReadFull(ar.fd, buf)
	if err == io.EOF {
		// No entries left.
		return nil
	}
	if err != nil || buf[entryLen-2] != '`' || buf[entryLen-1] != '\n' {
		log.Fatal("file is not an archive: bad entry")
	}
	entry := new(Entry)
	entry.name = strings.TrimRight(string(buf[:16]), " ")
	if len(entry.name) == 0 {
		log.Fatal("file is not an archive: bad name")
	}
	buf = buf[16:]
	str := string(buf)
	get := func(width, base, bitsize int) int64 {
		v, err := strconv.ParseInt(strings.TrimRight(str[:width], " "), base, bitsize)
		if err != nil {
			log.Fatal("file is not an archive: bad number in entry: ", err)
		}
		str = str[width:]
		return v
	}
	// %-16s%-12d%-6d%-6d%-8o%-10d`
	entry.mtime = get(12, 10, 64)
	entry.uid = int(get(6, 10, 32))
	entry.gid = int(get(6, 10, 32))
	entry.mode = os.FileMode(get(8, 8, 32))
	entry.size = get(10, 10, 64)
	return entry
}

// scan scans the archive and executes the specified action on each entry.
// When action returns, the file offset is at the start of the next entry.
func (ar *Archive) scan(action func(*Entry)) {
	for {
		entry := ar.readMetadata()
		if entry == nil {
			break
		}
		action(entry)
	}
}

// listEntry prints to standard output a line describing the entry.
func listEntry(entry *Entry, verbose bool) {
	if verbose {
		fmt.Fprintf(stdout, "%s\n", entry)
	} else {
		fmt.Fprintf(stdout, "%s\n", entry.name)
	}
}

// output copies the entry to the specified writer.
func (ar *Archive) output(entry *Entry, w io.Writer) {
	n, err := io.Copy(w, io.LimitReader(ar.fd, entry.size))
	if err != nil {
		log.Fatal(err)
	}
	if n != entry.size {
		log.Fatal("short file")
	}
	if entry.size&1 == 1 {
		_, err := ar.fd.Seek(1, io.SeekCurrent)
		if err != nil {
			log.Fatal(err)
		}
	}
}

// skip skips the entry without reading it.
func (ar *Archive) skip(entry *Entry) {
	size := entry.size
	if size&1 == 1 {
		size++
	}
	_, err := ar.fd.Seek(size, io.SeekCurrent)
	if err != nil {
		log.Fatal(err)
	}
}

// match reports whether the entry matches the argument list.
// If it does, it also drops the file from the to-be-processed list.
func (ar *Archive) match(entry *Entry) bool {
	if ar.matchAll {
		return true
	}
	for i, name := range ar.files {
		if entry.name == name {
			copy(ar.files[i:], ar.files[i+1:])
			ar.files = ar.files[:len(ar.files)-1]
			return true
		}
	}
	return false
}

// addFiles adds files to the archive. The archive is known to be
// sane and we are positioned at the end. No attempt is made
// to check for existing files.
func (ar *Archive) addFiles() {
	if len(ar.files) == 0 {
		usage()
	}
	for _, file := range ar.files {
		if verbose {
			fmt.Printf("%s\n", file)
		}

		if !isGoCompilerObjFile(file) {
			fd, err := os.Open(file)
			if err != nil {
				log.Fatal(err)
			}
			ar.addFile(fd)
			continue
		}

		aro := archive(file, os.O_RDONLY, nil)
		aro.scan(func(entry *Entry) {
			if entry.name != "_go_.o" {
				aro.skip(entry)
				return
			}
			ar.startFile(filepath.Base(file), 0, 0, 0, 0644, entry.size)
			aro.output(entry, ar.fd)
			ar.endFile()
		})
	}
	ar.files = nil
}

// FileLike abstracts the few methods we need, so we can test without needing real files.
type FileLike interface {
	Name() string
	Stat() (os.FileInfo, error)
	Read([]byte) (int, error)
	Close() error
}

// addFile adds a single file to the archive
func (ar *Archive) addFile(fd FileLike) {
	defer fd.Close()
	// Format the entry.
	// First, get its info.
	info, err := fd.Stat()
	if err != nil {
		log.Fatal(err)
	}
	// mtime, uid, gid are all zero so repeated builds produce identical output.
	mtime := int64(0)
	uid := 0
	gid := 0
	ar.startFile(info.Name(), mtime, uid, gid, info.Mode(), info.Size())
	n64, err := io.Copy(ar.fd, fd)
	if err != nil {
		log.Fatal("writing file: ", err)
	}
	if n64 != info.Size() {
		log.Fatalf("writing file: wrote %d bytes; file is size %d", n64, info.Size())
	}
	ar.endFile()
}

// startFile writes the archive entry header.
func (ar *Archive) startFile(name string, mtime int64, uid, gid int, mode os.FileMode, size int64) {
	n, err := fmt.Fprintf(ar.fd, entryHeader, exactly16Bytes(name), mtime, uid, gid, mode, size)
	if err != nil || n != entryLen {
		log.Fatal("writing entry header: ", err)
	}
	ar.pad = int(size & 1)
}

// endFile writes the archive entry tail (a single byte of padding, if the file size was odd).
func (ar *Archive) endFile() {
	if ar.pad != 0 {
		_, err := ar.fd.Write([]byte{0})
		if err != nil {
			log.Fatal("writing archive: ", err)
		}
		ar.pad = 0
	}
}

// addPkgdef adds the __.PKGDEF file to the archive, copied
// from the first Go object file on the file list, if any.
// The archive is known to be empty.
func (ar *Archive) addPkgdef() {
	done := false
	for _, file := range ar.files {
		if !isGoCompilerObjFile(file) {
			continue
		}
		aro := archive(file, os.O_RDONLY, nil)
		aro.scan(func(entry *Entry) {
			if entry.name != "__.PKGDEF" {
				aro.skip(entry)
				return
			}
			if verbose {
				fmt.Printf("__.PKGDEF # %s\n", file)
			}
			ar.startFile("__.PKGDEF", 0, 0, 0, 0644, entry.size)
			aro.output(entry, ar.fd)
			ar.endFile()
			done = true
		})
		if done {
			break
		}
	}
}

// exactly16Bytes truncates the string if necessary so it is at most 16 bytes long,
// then pads the result with spaces to be exactly 16 bytes.
// Fmt uses runes for its width calculation, but we need bytes in the entry header.
func exactly16Bytes(s string) string {
	for len(s) > 16 {
		_, wid := utf8.DecodeLastRuneInString(s)
		s = s[:len(s)-wid]
	}
	const sixteenSpaces = "                "
	s += sixteenSpaces[:16-len(s)]
	return s
}

// Finally, the actual commands. Each is an action.

// can be modified for testing.
var stdout io.Writer = os.Stdout

// printContents implements the 'p' command.
func (ar *Archive) printContents(entry *Entry) {
	if ar.match(entry) {
		if verbose {
			listEntry(entry, false)
		}
		ar.output(entry, stdout)
	} else {
		ar.skip(entry)
	}
}

// skipContents implements the first part of the 'r' command.
// It just scans the archive to make sure it's intact.
func (ar *Archive) skipContents(entry *Entry) {
	ar.skip(entry)
}

// tableOfContents implements the 't' command.
func (ar *Archive) tableOfContents(entry *Entry) {
	if ar.match(entry) {
		listEntry(entry, verbose)
	}
	ar.skip(entry)
}

// extractContents implements the 'x' command.
func (ar *Archive) extractContents(entry *Entry) {
	if ar.match(entry) {
		if verbose {
			listEntry(entry, false)
		}
		fd, err := os.OpenFile(entry.name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, entry.mode)
		if err != nil {
			log.Fatal(err)
		}
		ar.output(entry, fd)
		fd.Close()
	} else {
		ar.skip(entry)
	}
}

// isGoCompilerObjFile reports whether file is an object file created
// by the Go compiler.
func isGoCompilerObjFile(file string) bool {
	fd, err := os.Open(file)
	if err != nil {
		log.Fatal(err)
	}

	// Check for "!<arch>\n" header.
	buf := make([]byte, len(arHeader))
	_, err = io.ReadFull(fd, buf)
	if err != nil {
		if err == io.EOF {
			return false
		}
		log.Fatal(err)
	}
	if string(buf) != arHeader {
		return false
	}

	// Check for exactly two entries: "__.PKGDEF" and "_go_.o".
	match := []string{"__.PKGDEF", "_go_.o"}
	buf = make([]byte, entryLen)
	for {
		_, err := io.ReadFull(fd, buf)
		if err != nil {
			if err == io.EOF {
				// No entries left.
				return true
			}
			log.Fatal(err)
		}
		if buf[entryLen-2] != '`' || buf[entryLen-1] != '\n' {
			return false
		}

		name := strings.TrimRight(string(buf[:16]), " ")
		for {
			if len(match) == 0 {
				return false
			}
			var next string
			next, match = match[0], match[1:]
			if name == next {
				break
			}
		}

		size, err := strconv.ParseInt(strings.TrimRight(string(buf[48:58]), " "), 10, 64)
		if err != nil {
			return false
		}
		if size&1 != 0 {
			size++
		}

		_, err = fd.Seek(size, io.SeekCurrent)
		if err != nil {
			log.Fatal(err)
		}
	}
}
