// 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 git85 implements the radix 85 data encoding
// used in the Git version control system.
package git85

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

type CorruptInputError int64

func (e CorruptInputError) String() string {
	return "illegal git85 data at input byte " + strconv.Itoa64(int64(e))
}

const encode = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"

// The decodings are 1+ the actual value, so that the
// default zero value can be used to mean "not valid".
var decode = [256]uint8{
	'0': 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
	'A': 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
	24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
	'a': 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
	50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
	'!': 63,
	'#': 64, 65, 66, 67,
	'(': 68, 69, 70, 71,
	'-': 72,
	';': 73,
	'<': 74, 75, 76, 77,
	'@': 78,
	'^': 79, 80, 81,
	'{': 82, 83, 84, 85,
}

// Encode encodes src into EncodedLen(len(src))
// bytes of dst.  As a convenience, it returns the number
// of bytes written to dst, but this value is always EncodedLen(len(src)).
// Encode implements the radix 85 encoding used in the
// Git version control tool.
//
// The encoding splits src into chunks of at most 52 bytes
// and encodes each chunk on its own line.
func Encode(dst, src []byte) int {
	ndst := 0;
	for len(src) > 0 {
		n := len(src);
		if n > 52 {
			n = 52
		}
		if n <= 27 {
			dst[ndst] = byte('A' + n - 1)
		} else {
			dst[ndst] = byte('a' + n - 26 - 1)
		}
		ndst++;
		for i := 0; i < n; i += 4 {
			var v uint32;
			for j := 0; j < 4 && i+j < n; j++ {
				v |= uint32(src[i+j]) << uint(24-j*8)
			}
			for j := 4; j >= 0; j-- {
				dst[ndst+j] = encode[v%85];
				v /= 85;
			}
			ndst += 5;
		}
		dst[ndst] = '\n';
		ndst++;
		src = src[n:];
	}
	return ndst;
}

// EncodedLen returns the length of an encoding of n source bytes.
func EncodedLen(n int) int {
	if n == 0 {
		return 0
	}
	// 5 bytes per 4 bytes of input, rounded up.
	// 2 extra bytes for each line of 52 src bytes, rounded up.
	return (n+3)/4*5 + (n+51)/52*2;
}

var newline = []byte{'\n'}

// Decode decodes src into at most MaxDecodedLen(len(src))
// bytes, returning the actual number of bytes written to dst.
//
// If Decode encounters invalid input, it returns a CorruptInputError.
//
func Decode(dst, src []byte) (n int, err os.Error) {
	ndst := 0;
	nsrc := 0;
	for nsrc < len(src) {
		var l int;
		switch ch := int(src[nsrc]); {
		case 'A' <= ch && ch <= 'Z':
			l = ch - 'A' + 1
		case 'a' <= ch && ch <= 'z':
			l = ch - 'a' + 26 + 1
		default:
			return ndst, CorruptInputError(nsrc)
		}
		if nsrc+1+l > len(src) {
			return ndst, CorruptInputError(nsrc)
		}
		el := (l + 3) / 4 * 5;	// encoded len
		if nsrc+1+el+1 > len(src) || src[nsrc+1+el] != '\n' {
			return ndst, CorruptInputError(nsrc)
		}
		line := src[nsrc+1 : nsrc+1+el];
		for i := 0; i < el; i += 5 {
			var v uint32;
			for j := 0; j < 5; j++ {
				ch := decode[line[i+j]];
				if ch == 0 {
					return ndst, CorruptInputError(nsrc + 1 + i + j)
				}
				v = v*85 + uint32(ch-1);
			}
			for j := 0; j < 4; j++ {
				dst[ndst] = byte(v >> 24);
				v <<= 8;
				ndst++;
			}
		}
		// Last fragment may have run too far (but there was room in dst).
		// Back up.
		if l%4 != 0 {
			ndst -= 4 - l%4
		}
		nsrc += 1 + el + 1;
	}
	return ndst, nil;
}

func MaxDecodedLen(n int) int	{ return n / 5 * 4 }

// NewEncoder returns a new Git base85 stream encoder.  Data written to
// the returned writer will be encoded and then written to w.
// The Git encoding operates on 52-byte blocks; when finished
// writing, the caller must Close the returned encoder to flush any
// partially written blocks.
func NewEncoder(w io.Writer) io.WriteCloser	{ return &encoder{w: w} }

type encoder struct {
	w	io.Writer;
	err	os.Error;
	buf	[52]byte;
	nbuf	int;
	out	[1024]byte;
	nout	int;
}

func (e *encoder) Write(p []byte) (n int, err os.Error) {
	if e.err != nil {
		return 0, e.err
	}

	// Leading fringe.
	if e.nbuf > 0 {
		var i int;
		for i = 0; i < len(p) && e.nbuf < 52; i++ {
			e.buf[e.nbuf] = p[i];
			e.nbuf++;
		}
		n += i;
		p = p[i:];
		if e.nbuf < 52 {
			return
		}
		nout := Encode(&e.out, &e.buf);
		if _, e.err = e.w.Write(e.out[0:nout]); e.err != nil {
			return n, e.err
		}
		e.nbuf = 0;
	}

	// Large interior chunks.
	for len(p) >= 52 {
		nn := len(e.out) / (1 + 52/4*5 + 1) * 52;
		if nn > len(p) {
			nn = len(p) / 52 * 52
		}
		if nn > 0 {
			nout := Encode(&e.out, p[0:nn]);
			if _, e.err = e.w.Write(e.out[0:nout]); e.err != nil {
				return n, e.err
			}
		}
		n += nn;
		p = p[nn:];
	}

	// Trailing fringe.
	for i := 0; i < len(p); i++ {
		e.buf[i] = p[i]
	}
	e.nbuf = len(p);
	n += len(p);
	return;
}

func (e *encoder) Close() os.Error {
	// If there's anything left in the buffer, flush it out
	if e.err == nil && e.nbuf > 0 {
		nout := Encode(&e.out, e.buf[0:e.nbuf]);
		e.nbuf = 0;
		_, e.err = e.w.Write(e.out[0:nout]);
	}
	return e.err;
}

// NewDecoder returns a new Git base85 stream decoder.
func NewDecoder(r io.Reader) io.Reader	{ return &decoder{r: r} }

type decoder struct {
	r	io.Reader;
	err	os.Error;
	readErr	os.Error;
	buf	[1024]byte;
	nbuf	int;
	out	[]byte;
	outbuf	[1024]byte;
	off	int64;
}

func (d *decoder) Read(p []byte) (n int, err os.Error) {
	if len(p) == 0 {
		return 0, nil
	}

	for {
		// Copy leftover output from last decode.
		if len(d.out) > 0 {
			n = copy(p, d.out);
			d.out = d.out[n:];
			return;
		}

		// Out of decoded output.  Check errors.
		if d.err != nil {
			return 0, d.err
		}
		if d.readErr != nil {
			d.err = d.readErr;
			return 0, d.err;
		}

		// Read and decode more input.
		var nn int;
		nn, d.readErr = d.r.Read(d.buf[d.nbuf:]);
		d.nbuf += nn;

		// Send complete lines to Decode.
		nl := bytes.LastIndex(d.buf[0:d.nbuf], newline);
		if nl < 0 {
			continue
		}
		nn, d.err = Decode(&d.outbuf, d.buf[0:nl+1]);
		if e, ok := d.err.(CorruptInputError); ok {
			d.err = CorruptInputError(int64(e) + d.off)
		}
		d.out = d.outbuf[0:nn];
		d.nbuf = copy(&d.buf, d.buf[nl+1:d.nbuf]);
		d.off += int64(nl + 1);
	}
	panic("unreacahable");
}
