// 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:len(src)];
	}
	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:len(p)];
		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:len(p)];
	}

	// 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 = bytes.Copy(p, d.out);
			d.out = d.out[n:len(d.out)];
			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 : len(d.buf)]);
		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 = bytes.Copy(&d.buf, d.buf[nl+1 : d.nbuf]);
		d.off += int64(nl+1);
	}
	panic("unreacahable");
}
