// 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"
	"os"
	"reflect"
	"sync"
)

// A Decoder manages the receipt of type and data information read from the
// remote side of a connection.
type Decoder struct {
	mutex        sync.Mutex                              // each item must be received atomically
	r            io.Reader                               // source of the data
	wireType     map[typeId]*wireType                    // map from remote ID to local description
	decoderCache map[reflect.Type]map[typeId]**decEngine // cache of compiled engines
	ignorerCache map[typeId]**decEngine                  // ditto for ignored objects
	state        *decodeState                            // reads data from in-memory buffer
	countState   *decodeState                            // reads counts from wire
	buf          []byte
	countBuf     [9]byte // counts may be uint64s (unlikely!), require 9 bytes
	byteBuffer   *bytes.Buffer
	err          os.Error
}

// NewDecoder returns a new decoder that reads from the io.Reader.
func NewDecoder(r io.Reader) *Decoder {
	dec := new(Decoder)
	dec.r = r
	dec.wireType = make(map[typeId]*wireType)
	dec.state = newDecodeState(dec, &dec.byteBuffer) // buffer set in Decode()
	dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
	dec.ignorerCache = make(map[typeId]**decEngine)

	return dec
}

// recvType loads the definition of a type and reloads the Decoder's buffer.
func (dec *Decoder) recvType(id typeId) {
	// Have we already seen this type?  That's an error
	if dec.wireType[id] != nil {
		dec.err = os.ErrorString("gob: duplicate type received")
		return
	}

	// Type:
	wire := new(wireType)
	dec.err = dec.decode(tWireType, reflect.NewValue(wire))
	if dec.err != nil {
		return
	}
	// Remember we've seen this type.
	dec.wireType[id] = wire

	// Load the next parcel.
	dec.recv()
}

// Decode reads the next value from the connection and stores
// it in the data represented by the empty interface value.
// The value underlying e must be the correct type for the next
// data item received, and must be a pointer.
func (dec *Decoder) Decode(e interface{}) os.Error {
	value := reflect.NewValue(e)
	// If e represents a value as opposed to a pointer, the answer won't
	// get back to the caller.  Make sure it's a pointer.
	if value.Type().Kind() != reflect.Ptr {
		dec.err = os.ErrorString("gob: attempt to decode into a non-pointer")
		return dec.err
	}
	return dec.DecodeValue(value)
}

// recv reads the next count-delimited item from the input. It is the converse
// of Encoder.send.
func (dec *Decoder) recv() {
	// Read a count.
	var nbytes uint64
	nbytes, dec.err = decodeUintReader(dec.r, dec.countBuf[0:])
	if dec.err != nil {
		return
	}
	// Allocate the buffer.
	if nbytes > uint64(len(dec.buf)) {
		dec.buf = make([]byte, nbytes+1000)
	}
	dec.byteBuffer = bytes.NewBuffer(dec.buf[0:nbytes])

	// Read the data
	_, dec.err = io.ReadFull(dec.r, dec.buf[0:nbytes])
	if dec.err != nil {
		if dec.err == os.EOF {
			dec.err = io.ErrUnexpectedEOF
		}
		return
	}
}

// decodeValueFromBuffer grabs the next value from the input. The Decoder's
// buffer already contains data.  If the next item in the buffer is a type
// descriptor, it may be necessary to reload the buffer, but recvType does that.
func (dec *Decoder) decodeValueFromBuffer(value reflect.Value, ignoreInterfaceValue, countPresent bool) {
	for dec.state.b.Len() > 0 {
		// Receive a type id.
		id := typeId(decodeInt(dec.state))

		// Is it a new type?
		if id < 0 { // 0 is the error state, handled above
			// If the id is negative, we have a type.
			dec.recvType(-id)
			if dec.err != nil {
				break
			}
			continue
		}

		// Make sure the type has been defined already or is a builtin type (for
		// top-level singleton values).
		if dec.wireType[id] == nil && builtinIdToType[id] == nil {
			dec.err = errBadType
			break
		}
		// An interface value is preceded by a byte count.
		if countPresent {
			count := int(decodeUint(dec.state))
			if ignoreInterfaceValue {
				// An interface value is preceded by a byte count. Just skip that many bytes.
				dec.state.b.Next(int(count))
				break
			}
			// Otherwise fall through and decode it.
		}
		dec.err = dec.decode(id, value)
		break
	}
}

// DecodeValue reads the next value from the connection and stores
// it in the data represented by the reflection value.
// The value must be the correct type for the next
// data item received.
func (dec *Decoder) DecodeValue(value reflect.Value) os.Error {
	// Make sure we're single-threaded through here.
	dec.mutex.Lock()
	defer dec.mutex.Unlock()

	dec.err = nil
	dec.recv()
	if dec.err != nil {
		return dec.err
	}
	dec.decodeValueFromBuffer(value, false, false)
	return dec.err
}

// If debug.go is compiled into the program , debugFunc prints a human-readable
// representation of the gob data read from r by calling that file's Debug function.
// Otherwise it is nil.
var debugFunc func(io.Reader)
