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

type kind reflect.Type

// Reflection types are themselves interface values holding structs
// describing the type.  Each type has a different struct so that struct can
// be the kind.  For example, if typ is the reflect type for an int8, typ is
// a pointer to a reflect.Int8Type struct; if typ is the reflect type for a
// function, typ is a pointer to a reflect.FuncType struct; we use the type
// of that pointer as the kind.

// typeKind returns a reflect.Type representing typ's kind.  The kind is the
// general kind of type:
//	int8, int16, int, uint, float, func, chan, struct, and so on.
// That is, all struct types have the same kind, all func types have the same
// kind, all int8 types have the same kind, and so on.
func typeKind(typ reflect.Type) kind {
	return kind(reflect.Typeof(typ));
}

// valueKind returns the kind of the value type
// stored inside the interface v.
func valueKind(v interface{}) reflect.Type {
	return typeKind(reflect.Typeof(v));
}

// A typeId represents a gob Type as an integer that can be passed on the wire.
// Internally, typeIds are used as keys to a map to recover the underlying type info.
type typeId int32

var nextId	typeId	// incremented for each new type we build
var typeLock	sync.Mutex	// set while building a type

type gobType interface {
	id()	typeId;
	setId(id typeId);
	Name()	string;
	String()	string;
	safeString(seen map[typeId] bool)	string;
}

var types = make(map[reflect.Type] gobType)
var idToType = make(map[typeId] gobType)

func setTypeId(typ gobType) {
	nextId++;
	typ.setId(nextId);
	idToType[nextId] = typ;
}

func (t typeId) gobType() gobType {
	if t == 0 {
		return nil
	}
	return idToType[t]
}

// String returns the string representation of the type associated with the typeId.
func (t typeId) String() string {
	return t.gobType().String()
}

// Name returns the name of the type associated with the typeId.
func (t typeId) Name() string {
	return t.gobType().Name()
}

// Common elements of all types.
type commonType struct {
	name	string;
	_id	typeId;
}

func (t *commonType) id() typeId {
	return t._id
}

func (t *commonType) setId(id typeId) {
	t._id = id
}

func (t *commonType) String() string {
	return t.name
}

func (t *commonType) safeString(seen map[typeId] bool) string {
	return t.name
}

func (t *commonType) Name() string {
	return t.name
}

// Create and check predefined types
// The string for tBytes is "bytes" not "[]byte" to signify its specialness.

var tBool = bootstrapType("bool", false, 1)
var tInt = bootstrapType("int", int(0), 2)
var tUint = bootstrapType("uint", uint(0), 3)
var tFloat = bootstrapType("float", float64(0), 4)
var tBytes = bootstrapType("bytes", make([]byte, 0), 5)
var tString = bootstrapType("string", "", 6)

// Predefined because it's needed by the Decoder
var tWireType = getTypeInfoNoError(reflect.Typeof(wireType{})).id

func init() {
	checkId(7, tWireType);
	checkId(8, getTypeInfoNoError(reflect.Typeof(structType{})).id);
	checkId(9, getTypeInfoNoError(reflect.Typeof(commonType{})).id);
	checkId(10, getTypeInfoNoError(reflect.Typeof(fieldType{})).id);
}

// Array type
type arrayType struct {
	commonType;
	Elem	typeId;
	Len	int;
}

func newArrayType(name string, elem gobType, length int) *arrayType {
	a := &arrayType{ commonType{ name: name }, elem.id(), length };
	setTypeId(a);
	return a;
}

func (a *arrayType) safeString(seen map[typeId] bool) string {
	if _, ok := seen[a._id]; ok {
		return a.name
	}
	seen[a._id] = true;
	return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen));
}

func (a *arrayType) String() string {
	return a.safeString(make(map[typeId] bool))
}

// Slice type
type sliceType struct {
	commonType;
	Elem	typeId;
}

func newSliceType(name string, elem gobType) *sliceType {
	s := &sliceType{ commonType{ name: name }, elem.id() };
	setTypeId(s);
	return s;
}

func (s *sliceType) safeString(seen map[typeId] bool) string {
	if _, ok := seen[s._id]; ok {
		return s.name
	}
	seen[s._id] = true;
	return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen));
}

func (s *sliceType) String() string {
	return s.safeString(make(map[typeId] bool))
}

// Struct type
type fieldType struct {
	name	string;
	id	typeId;
}

type structType struct {
	commonType;
	field	[]*fieldType;
}

func (s *structType) safeString(seen map[typeId] bool) string {
	if s == nil {
		return "<nil>"
	}
	if _, ok := seen[s._id]; ok {
		return s.name
	}
	seen[s._id] = true;
	str := s.name + " = struct { ";
	for _, f := range s.field {
		str += fmt.Sprintf("%s %s; ", f.name, f.id.gobType().safeString(seen));
	}
	str += "}";
	return str;
}

func (s *structType) String() string {
	return s.safeString(make(map[typeId] bool))
}

func newStructType(name string) *structType {
	s := &structType{ commonType{ name: name }, nil };
	setTypeId(s);
	return s;
}

// Step through the indirections on a type to discover the base type.
// Return the number of indirections.
func indirect(t reflect.Type) (rt reflect.Type, count int) {
	rt = t;
	for {
		pt, ok := rt.(*reflect.PtrType);
		if !ok {
			break;
		}
		rt = pt.Elem();
		count++;
	}
	return;
}

func newTypeObject(name string, rt reflect.Type) (gobType, os.Error) {
	switch t := rt.(type) {
	// All basic types are easy: they are predefined.
	case *reflect.BoolType:
		return tBool.gobType(), nil

	case *reflect.IntType:
		return tInt.gobType(), nil
	case *reflect.Int8Type:
		return tInt.gobType(), nil
	case *reflect.Int16Type:
		return tInt.gobType(), nil
	case *reflect.Int32Type:
		return tInt.gobType(), nil
	case *reflect.Int64Type:
		return tInt.gobType(), nil

	case *reflect.UintType:
		return tUint.gobType(), nil
	case *reflect.Uint8Type:
		return tUint.gobType(), nil
	case *reflect.Uint16Type:
		return tUint.gobType(), nil
	case *reflect.Uint32Type:
		return tUint.gobType(), nil
	case *reflect.Uint64Type:
		return tUint.gobType(), nil
	case *reflect.UintptrType:
		return tUint.gobType(), nil

	case *reflect.FloatType:
		return tFloat.gobType(), nil
	case *reflect.Float32Type:
		return tFloat.gobType(), nil
	case *reflect.Float64Type:
		return tFloat.gobType(), nil

	case *reflect.StringType:
		return tString.gobType(), nil

	case *reflect.ArrayType:
		gt, err := getType("", t.Elem());
		if err != nil {
			return nil, err
		}
		return newArrayType(name, gt, t.Len()), nil;

	case *reflect.SliceType:
		// []byte == []uint8 is a special case
		if _, ok := t.Elem().(*reflect.Uint8Type); ok {
			return tBytes.gobType(), nil
		}
		gt, err := getType(t.Elem().Name(), t.Elem());
		if err != nil {
			return nil, err
		}
		return newSliceType(name, gt), nil;

	case *reflect.StructType:
		// Install the struct type itself before the fields so recursive
		// structures can be constructed safely.
		strType := newStructType(name);
		types[rt] = strType;
		idToType[strType.id()] = strType;
		field := make([]*fieldType, t.NumField());
		for i := 0; i < t.NumField(); i++ {
			f := t.Field(i);
			typ, _ := indirect(f.Type);
			tname := typ.Name();
			if tname == "" {
				tname = f.Type.String();
			}
			gt, err := getType(tname, f.Type);
			if err != nil {
				return nil, err
			}
			field[i] =  &fieldType{ f.Name, gt.id() };
		}
		strType.field = field;
		return strType, nil;

	default:
		return nil, os.ErrorString("gob NewTypeObject can't handle type: " + rt.String());
	}
	return nil, nil
}

// getType returns the Gob type describing the given reflect.Type.
// typeLock must be held.
func getType(name string, rt reflect.Type) (gobType, os.Error) {
	// Flatten the data structure by collapsing out pointers
	for {
		pt, ok := rt.(*reflect.PtrType);
		if !ok {
			break;
		}
		rt = pt.Elem();
	}
	typ, present := types[rt];
	if present {
		return typ, nil
	}
	typ, err := newTypeObject(name, rt);
	if err == nil {
		types[rt] = typ
	}
	return typ, err
}

func checkId(want, got typeId) {
	if want != got {
		panicln("bootstrap type wrong id:", got.Name(), got, "not", want);
	}
}

// used for building the basic types; called only from init()
func bootstrapType(name string, e interface{}, expect typeId) typeId {
	rt := reflect.Typeof(e);
	_, present := types[rt];
	if present {
		panicln("bootstrap type already present:", name);
	}
	typ := &commonType{ name: name };
	types[rt] = typ;
	setTypeId(typ);
	checkId(expect, nextId);
	return nextId
}

// Representation of the information we send and receive about this type.
// Each value we send is preceded by its type definition: an encoded int.
// However, the very first time we send the value, we first send the pair
// (-id, wireType).
// For bootstrapping purposes, we assume that the recipient knows how
// to decode a wireType; it is exactly the wireType struct here, interpreted
// using the gob rules for sending a structure, except that we assume the
// ids for wireType and structType are known.  The relevant pieces
// are built in encode.go's init() function.

type wireType struct {
	s	*structType;
}

func (w *wireType) name() string {
	// generalize once we can have non-struct types on the wire.
	return w.s.name
}

type typeInfo struct {
	id	typeId;
	encoder	*encEngine;
	wire	*wireType;
}

var typeInfoMap = make(map[reflect.Type] *typeInfo)	// protected by typeLock

// The reflection type must have all its indirections processed out.
// typeLock must be held.
func getTypeInfo(rt reflect.Type) (*typeInfo, os.Error) {
	if _, ok := rt.(*reflect.PtrType); ok {
		panicln("pointer type in getTypeInfo:", rt.String())
	}
	info, ok := typeInfoMap[rt];
	if !ok {
		info = new(typeInfo);
		name := rt.Name();
		gt, err := getType(name, rt);
		if err != nil {
			return nil, err
		}
		info.id = gt.id();
		// assume it's a struct type
		info.wire = &wireType{info.id.gobType().(*structType)};
		typeInfoMap[rt] = info;
	}
	return info, nil;
}

// Called only when a panic is acceptable and unexpected.
func getTypeInfoNoError(rt reflect.Type) *typeInfo {
	t, err := getTypeInfo(rt);
	if err != nil {
		panicln("getTypeInfo:", err.String());
	}
	return t
}
