// 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 (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"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
	godoc 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 (or if necessary creates) the named archive.
func archive(name string, mode int, files []string) *Archive {
	fd, err := os.OpenFile(name, mode, 0)
	if err != nil && mode&^os.O_TRUNC == os.O_RDWR && os.IsNotExist(err) {
		fd, err = create(name)
	}
	if err != nil {
		log.Fatal(err)
	}
	mustBeArchive(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) (*os.File, error) {
	fd, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return nil, err
	}
	fmt.Fprint(fd, arHeader)
	fd.Seek(0, 0)
	return fd, nil
}

// mustBeArchive verifies the header of the file. It assumes the file offset
// is 0 coming in, and leaves it positioned immediately after the header.
func mustBeArchive(fd *os.File) {
	buf := make([]byte, len(arHeader))
	_, err := io.ReadFull(fd, buf)
	if err != nil || string(buf) != arHeader {
		log.Fatal("file is not an archive: bad header")
	}
}

// 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(ar *Archive, 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, 1)
		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, 1)
	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)
		}
		fd, err := os.Open(file)
		if err != nil {
			log.Fatal(err)
		}
		ar.addFile(fd)
	}
	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() {
	for _, file := range ar.files {
		pkgdef, err := readPkgdef(file)
		if err != nil {
			continue
		}
		if verbose {
			fmt.Printf("__.PKGDEF # %s\n", file)
		}
		ar.startFile("__.PKGDEF", 0, 0, 0, 0644, int64(len(pkgdef)))
		_, err = ar.fd.Write(pkgdef)
		if err != nil {
			log.Fatal("writing __.PKGDEF: ", err)
		}
		ar.endFile()
		break
	}
}

// readPkgdef extracts the __.PKGDEF data from a Go object file.
func readPkgdef(file string) (data []byte, err error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	// Read from file, collecting header for __.PKGDEF.
	// The header is from the beginning of the file until a line
	// containing just "!". The first line must begin with "go object ".
	rbuf := bufio.NewReader(f)
	var wbuf bytes.Buffer
	for {
		line, err := rbuf.ReadBytes('\n')
		if err != nil {
			return nil, err
		}
		if wbuf.Len() == 0 && !bytes.HasPrefix(line, []byte("go object ")) {
			return nil, errors.New("not a Go object file")
		}
		if bytes.Equal(line, []byte("!\n")) {
			break
		}
		wbuf.Write(line)
	}
	return wbuf.Bytes(), nil
}

// 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(ar, 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(ar, entry, verbose)
	}
	ar.skip(entry)
}

// extractContents implements the 'x' command.
func (ar *Archive) extractContents(entry *Entry) {
	if ar.match(entry) {
		if verbose {
			listEntry(ar, 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)
	}
}
