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

import (
	"bytes"
	"io"
	"math"
	"os"
	"reflect"
	"unsafe"
)

const uint64Size = unsafe.Sizeof(uint64(0))

// The global execution state of an instance of the encoder.
// Field numbers are delta encoded and always increase. The field
// number is initialized to -1 so 0 comes out as delta(1). A delta of
// 0 terminates the structure.
type encoderState struct {
	b        *bytes.Buffer
	err      os.Error             // error encountered during encoding;
	fieldnum int                  // the last field number written.
	buf      [1 + uint64Size]byte // buffer used by the encoder; here to avoid allocation.
}

// Unsigned integers have a two-state encoding.  If the number is less
// than 128 (0 through 0x7F), its value is written directly.
// Otherwise the value is written in big-endian byte order preceded
// by the byte length, negated.

// encodeUint writes an encoded unsigned integer to state.b.  Sets state.err.
// If state.err is already non-nil, it does nothing.
func encodeUint(state *encoderState, x uint64) {
	if state.err != nil {
		return
	}
	if x <= 0x7F {
		state.err = state.b.WriteByte(uint8(x))
		return
	}
	var n, m int
	m = uint64Size
	for n = 1; x > 0; n++ {
		state.buf[m] = uint8(x & 0xFF)
		x >>= 8
		m--
	}
	state.buf[m] = uint8(-(n - 1))
	n, state.err = state.b.Write(state.buf[m : uint64Size+1])
}

// encodeInt writes an encoded signed integer to state.w.
// The low bit of the encoding says whether to bit complement the (other bits of the) uint to recover the int.
// Sets state.err. If state.err is already non-nil, it does nothing.
func encodeInt(state *encoderState, i int64) {
	var x uint64
	if i < 0 {
		x = uint64(^i<<1) | 1
	} else {
		x = uint64(i << 1)
	}
	encodeUint(state, uint64(x))
}

type encOp func(i *encInstr, state *encoderState, p unsafe.Pointer)

// The 'instructions' of the encoding machine
type encInstr struct {
	op     encOp
	field  int     // field number
	indir  int     // how many pointer indirections to reach the value in the struct
	offset uintptr // offset in the structure of the field to encode
}

// Emit a field number and update the state to record its value for delta encoding.
// If the instruction pointer is nil, do nothing
func (state *encoderState) update(instr *encInstr) {
	if instr != nil {
		encodeUint(state, uint64(instr.field-state.fieldnum))
		state.fieldnum = instr.field
	}
}

// Each encoder is responsible for handling any indirections associated
// with the data structure.  If any pointer so reached is nil, no bytes are written.
// If the data item is zero, no bytes are written.
// Otherwise, the output (for a scalar) is the field number, as an encoded integer,
// followed by the field data in its appropriate format.

func encIndirect(p unsafe.Pointer, indir int) unsafe.Pointer {
	for ; indir > 0; indir-- {
		p = *(*unsafe.Pointer)(p)
		if p == nil {
			return unsafe.Pointer(nil)
		}
	}
	return p
}

func encBool(i *encInstr, state *encoderState, p unsafe.Pointer) {
	b := *(*bool)(p)
	if b {
		state.update(i)
		encodeUint(state, 1)
	}
}

func encInt(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := int64(*(*int)(p))
	if v != 0 {
		state.update(i)
		encodeInt(state, v)
	}
}

func encUint(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := uint64(*(*uint)(p))
	if v != 0 {
		state.update(i)
		encodeUint(state, v)
	}
}

func encInt8(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := int64(*(*int8)(p))
	if v != 0 {
		state.update(i)
		encodeInt(state, v)
	}
}

func encUint8(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := uint64(*(*uint8)(p))
	if v != 0 {
		state.update(i)
		encodeUint(state, v)
	}
}

func encInt16(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := int64(*(*int16)(p))
	if v != 0 {
		state.update(i)
		encodeInt(state, v)
	}
}

func encUint16(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := uint64(*(*uint16)(p))
	if v != 0 {
		state.update(i)
		encodeUint(state, v)
	}
}

func encInt32(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := int64(*(*int32)(p))
	if v != 0 {
		state.update(i)
		encodeInt(state, v)
	}
}

func encUint32(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := uint64(*(*uint32)(p))
	if v != 0 {
		state.update(i)
		encodeUint(state, v)
	}
}

func encInt64(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := *(*int64)(p)
	if v != 0 {
		state.update(i)
		encodeInt(state, v)
	}
}

func encUint64(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := *(*uint64)(p)
	if v != 0 {
		state.update(i)
		encodeUint(state, v)
	}
}

func encUintptr(i *encInstr, state *encoderState, p unsafe.Pointer) {
	v := uint64(*(*uintptr)(p))
	if v != 0 {
		state.update(i)
		encodeUint(state, v)
	}
}

// Floating-point numbers are transmitted as uint64s holding the bits
// of the underlying representation.  They are sent byte-reversed, with
// the exponent end coming out first, so integer floating point numbers
// (for example) transmit more compactly.  This routine does the
// swizzling.
func floatBits(f float64) uint64 {
	u := math.Float64bits(f)
	var v uint64
	for i := 0; i < 8; i++ {
		v <<= 8
		v |= u & 0xFF
		u >>= 8
	}
	return v
}

func encFloat(i *encInstr, state *encoderState, p unsafe.Pointer) {
	f := float(*(*float)(p))
	if f != 0 {
		v := floatBits(float64(f))
		state.update(i)
		encodeUint(state, v)
	}
}

func encFloat32(i *encInstr, state *encoderState, p unsafe.Pointer) {
	f := float32(*(*float32)(p))
	if f != 0 {
		v := floatBits(float64(f))
		state.update(i)
		encodeUint(state, v)
	}
}

func encFloat64(i *encInstr, state *encoderState, p unsafe.Pointer) {
	f := *(*float64)(p)
	if f != 0 {
		state.update(i)
		v := floatBits(f)
		encodeUint(state, v)
	}
}

// Byte arrays are encoded as an unsigned count followed by the raw bytes.
func encUint8Array(i *encInstr, state *encoderState, p unsafe.Pointer) {
	b := *(*[]byte)(p)
	if len(b) > 0 {
		state.update(i)
		encodeUint(state, uint64(len(b)))
		state.b.Write(b)
	}
}

// Strings are encoded as an unsigned count followed by the raw bytes.
func encString(i *encInstr, state *encoderState, p unsafe.Pointer) {
	s := *(*string)(p)
	if len(s) > 0 {
		state.update(i)
		encodeUint(state, uint64(len(s)))
		io.WriteString(state.b, s)
	}
}

// The end of a struct is marked by a delta field number of 0.
func encStructTerminator(i *encInstr, state *encoderState, p unsafe.Pointer) {
	encodeUint(state, 0)
}

// Execution engine

// The encoder engine is an array of instructions indexed by field number of the encoding
// data, typically a struct.  It is executed top to bottom, walking the struct.
type encEngine struct {
	instr []encInstr
}

func encodeStruct(engine *encEngine, b *bytes.Buffer, basep uintptr) os.Error {
	state := new(encoderState)
	state.b = b
	state.fieldnum = -1
	for i := 0; i < len(engine.instr); i++ {
		instr := &engine.instr[i]
		p := unsafe.Pointer(basep + instr.offset)
		if instr.indir > 0 {
			if p = encIndirect(p, instr.indir); p == nil {
				continue
			}
		}
		instr.op(instr, state, p)
		if state.err != nil {
			break
		}
	}
	return state.err
}

func encodeArray(b *bytes.Buffer, p uintptr, op encOp, elemWid uintptr, length int, elemIndir int) os.Error {
	state := new(encoderState)
	state.b = b
	state.fieldnum = -1
	encodeUint(state, uint64(length))
	for i := 0; i < length && state.err == nil; i++ {
		elemp := p
		up := unsafe.Pointer(elemp)
		if elemIndir > 0 {
			if up = encIndirect(up, elemIndir); up == nil {
				state.err = os.ErrorString("gob: encodeArray: nil element")
				break
			}
			elemp = uintptr(up)
		}
		op(nil, state, unsafe.Pointer(elemp))
		p += uintptr(elemWid)
	}
	return state.err
}

var encOpMap = map[reflect.Type]encOp{
	valueKind(false): encBool,
	valueKind(int(0)): encInt,
	valueKind(int8(0)): encInt8,
	valueKind(int16(0)): encInt16,
	valueKind(int32(0)): encInt32,
	valueKind(int64(0)): encInt64,
	valueKind(uint(0)): encUint,
	valueKind(uint8(0)): encUint8,
	valueKind(uint16(0)): encUint16,
	valueKind(uint32(0)): encUint32,
	valueKind(uint64(0)): encUint64,
	valueKind(uintptr(0)): encUintptr,
	valueKind(float(0)): encFloat,
	valueKind(float32(0)): encFloat32,
	valueKind(float64(0)): encFloat64,
	valueKind("x"): encString,
}

// Return the encoding op for the base type under rt and
// the indirection count to reach it.
func encOpFor(rt reflect.Type) (encOp, int, os.Error) {
	typ, indir := indirect(rt)
	op, ok := encOpMap[reflect.Typeof(typ)]
	if !ok {
		typ, _ := indirect(rt)
		// Special cases
		switch t := typ.(type) {
		case *reflect.SliceType:
			if _, ok := t.Elem().(*reflect.Uint8Type); ok {
				op = encUint8Array
				break
			}
			// Slices have a header; we decode it to find the underlying array.
			elemOp, indir, err := encOpFor(t.Elem())
			if err != nil {
				return nil, 0, err
			}
			op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
				slice := (*reflect.SliceHeader)(p)
				if slice.Len == 0 {
					return
				}
				state.update(i)
				state.err = encodeArray(state.b, slice.Data, elemOp, t.Elem().Size(), int(slice.Len), indir)
			}
		case *reflect.ArrayType:
			// True arrays have size in the type.
			elemOp, indir, err := encOpFor(t.Elem())
			if err != nil {
				return nil, 0, err
			}
			op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
				state.update(i)
				state.err = encodeArray(state.b, uintptr(p), elemOp, t.Elem().Size(), t.Len(), indir)
			}
		case *reflect.StructType:
			// Generate a closure that calls out to the engine for the nested type.
			_, err := getEncEngine(typ)
			if err != nil {
				return nil, 0, err
			}
			info := mustGetTypeInfo(typ)
			op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
				state.update(i)
				// indirect through info to delay evaluation for recursive structs
				state.err = encodeStruct(info.encoder, state.b, uintptr(p))
			}
		}
	}
	if op == nil {
		return op, indir, os.ErrorString("gob enc: can't happen: encode type" + rt.String())
	}
	return op, indir, nil
}

// The local Type was compiled from the actual value, so we know it's compatible.
func compileEnc(rt reflect.Type) (*encEngine, os.Error) {
	srt, ok := rt.(*reflect.StructType)
	if !ok {
		panicln("can't happen: non-struct")
	}
	engine := new(encEngine)
	engine.instr = make([]encInstr, srt.NumField()+1) // +1 for terminator
	for fieldnum := 0; fieldnum < srt.NumField(); fieldnum++ {
		f := srt.Field(fieldnum)
		op, indir, err := encOpFor(f.Type)
		if err != nil {
			return nil, err
		}
		engine.instr[fieldnum] = encInstr{op, fieldnum, indir, uintptr(f.Offset)}
	}
	engine.instr[srt.NumField()] = encInstr{encStructTerminator, 0, 0, 0}
	return engine, nil
}

// typeLock must be held (or we're in initialization and guaranteed single-threaded).
// The reflection type must have all its indirections processed out.
func getEncEngine(rt reflect.Type) (*encEngine, os.Error) {
	info, err := getTypeInfo(rt)
	if err != nil {
		return nil, err
	}
	if info.encoder == nil {
		// mark this engine as underway before compiling to handle recursive types.
		info.encoder = new(encEngine)
		info.encoder, err = compileEnc(rt)
	}
	return info.encoder, err
}

func encode(b *bytes.Buffer, e interface{}) os.Error {
	// Dereference down to the underlying object.
	rt, indir := indirect(reflect.Typeof(e))
	v := reflect.NewValue(e)
	for i := 0; i < indir; i++ {
		v = reflect.Indirect(v)
	}
	if _, ok := v.(*reflect.StructValue); !ok {
		return os.ErrorString("gob: encode can't handle " + v.Type().String())
	}
	typeLock.Lock()
	engine, err := getEncEngine(rt)
	typeLock.Unlock()
	if err != nil {
		return err
	}
	return encodeStruct(engine, b, v.Addr())
}
