// Copyright 2009 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 tar

// TODO(dsymonds):
//   - pax extensions

import (
	"bytes";
	"io";
	"os";
	"strconv";
)

var (
	HeaderError os.Error = os.ErrorString("invalid tar header");
)

// A Reader provides sequential access to the contents of a tar archive.
// A tar archive consists of a sequence of files.
// The Next method advances to the next file in the archive (including the first),
// and then it can be treated as an io.Reader to access the file's data.
//
// Example:
//	tr := tar.NewReader(r);
//	for {
//		hdr, err := tr.Next();
//		if err != nil {
//			// handle error
//		}
//		if hdr == nil {
//			// end of tar archive
//			break
//		}
//		io.Copy(tr, data);
//	}
type Reader struct {
	r io.Reader;
	err os.Error;
	nb int64;	// number of unread bytes for current file entry
	pad int64;	// amount of padding (ignored) after current file entry
}

// NewReader creates a new Reader reading from r.
func NewReader(r io.Reader) *Reader {
	return &Reader{ r: r }
}

// Next advances to the next entry in the tar archive.
func (tr *Reader) Next() (*Header, os.Error) {
	var hdr *Header;
	if tr.err == nil {
		tr.skipUnread();
	}
	if tr.err == nil {
		hdr = tr.readHeader();
	}
	return hdr, tr.err
}

// Parse bytes as a NUL-terminated C-style string.
// If a NUL byte is not found then the whole slice is returned as a string.
func cString(b []byte) string {
	n := 0;
	for n < len(b) && b[n] != 0 {
		n++;
	}
	return string(b[0:n])
}

func (tr *Reader) octal(b []byte) int64 {
	// Removing leading spaces.
	for len(b) > 0 && b[0] == ' ' {
		b = b[1:len(b)];
	}
	// Removing trailing NULs and spaces.
	for len(b) > 0 && (b[len(b)-1] == ' ' || b[len(b)-1] == '\x00') {
		b = b[0:len(b)-1];
	}
	x, err := strconv.Btoui64(cString(b), 8);
	if err != nil {
		tr.err = err;
	}
	return int64(x)
}

type ignoreWriter struct {}
func (ignoreWriter) Write(b []byte) (n int, err os.Error) {
	return len(b), nil
}

// Skip any unread bytes in the existing file entry, as well as any alignment padding.
func (tr *Reader) skipUnread() {
	nr := tr.nb + tr.pad;	// number of bytes to skip

	if sr, ok := tr.r.(io.Seeker); ok {
		_, tr.err = sr.Seek(nr, 1);
	} else {
		_, tr.err = io.Copyn(tr.r, ignoreWriter{}, nr);
	}
	tr.nb, tr.pad = 0, 0;
}

func (tr *Reader) verifyChecksum(header []byte) bool {
	if tr.err != nil {
		return false
	}

	given := tr.octal(header[148:156]);
	unsigned, signed := checksum(header);
	return given == unsigned || given == signed
}

func (tr *Reader) readHeader() *Header {
	header := make([]byte, blockSize);
	if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil {
		return nil
	}

	// Two blocks of zero bytes marks the end of the archive.
	if bytes.Equal(header, zeroBlock[0:blockSize]) {
		if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil {
			return nil
		}
		if !bytes.Equal(header, zeroBlock[0:blockSize]) {
			tr.err = HeaderError;
		}
		return nil
	}

	if !tr.verifyChecksum(header) {
		tr.err = HeaderError;
		return nil
	}

	// Unpack
	hdr := new(Header);
	s := slicer(header);

	hdr.Name = cString(s.next(100));
	hdr.Mode = tr.octal(s.next(8));
	hdr.Uid = tr.octal(s.next(8));
	hdr.Gid = tr.octal(s.next(8));
	hdr.Size = tr.octal(s.next(12));
	hdr.Mtime = tr.octal(s.next(12));
	s.next(8);  // chksum
	hdr.Typeflag = s.next(1)[0];
	hdr.Linkname = cString(s.next(100));

	// The remainder of the header depends on the value of magic.
	// The original (v7) version of tar had no explicit magic field,
	// so its magic bytes, like the rest of the block, are NULs.
	magic := string(s.next(8));  // contains version field as well.
	var format string;
	switch magic {
	case "ustar\x0000":  // POSIX tar (1003.1-1988)
		if string(header[508:512]) == "tar\x00" {
			format = "star";
		} else {
			format = "posix";
		}
	case "ustar  \x00":  // old GNU tar
		format = "gnu";
	}

	switch format {
	case "posix", "gnu", "star":
		hdr.Uname = cString(s.next(32));
		hdr.Gname = cString(s.next(32));
		devmajor := s.next(8);
		devminor := s.next(8);
		if hdr.Typeflag == TypeChar || hdr.Typeflag == TypeBlock {
			hdr.Devmajor = tr.octal(devmajor);
			hdr.Devminor = tr.octal(devminor);
		}
		var prefix string;
		switch format {
		case "posix", "gnu":
			prefix = cString(s.next(155));
		case "star":
			prefix = cString(s.next(131));
			hdr.Atime = tr.octal(s.next(12));
			hdr.Ctime = tr.octal(s.next(12));
		}
		if len(prefix) > 0 {
			hdr.Name = prefix + "/" + hdr.Name;
		}
	}

	if tr.err != nil {
		tr.err = HeaderError;
		return nil
	}

	// Maximum value of hdr.Size is 64 GB (12 octal digits),
	// so there's no risk of int64 overflowing.
	tr.nb = int64(hdr.Size);
	tr.pad = -tr.nb & (blockSize - 1);  // blockSize is a power of two

	return hdr
}

// Read reads from the current entry in the tar archive.
// It returns 0, nil when it reaches the end of that entry,
// until Next is called to advance to the next entry.
func (tr *Reader) Read(b []uint8) (n int, err os.Error) {
	if int64(len(b)) > tr.nb {
		b = b[0:tr.nb];
	}
	n, err = tr.r.Read(b);
	tr.nb -= int64(n);
	tr.err = err;
	return
}
