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

// Reflection library.
// Handling values.

package reflect

import (
	"reflect";
	"unsafe";
)

// Addr is shorthand for unsafe.Pointer and is used to represent the address of Values.
type Addr unsafe.Pointer

func equalType(a, b Type) bool {
	return a.String() == b.String()
}

// Value is the generic interface to reflection values.  Once its Kind is known,
// such as BoolKind, the Value can be narrowed to the appropriate, more
// specific interface, such as BoolValue.  Such narrowed values still implement
// the Value interface.
type Value interface {
	// The kind of thing described: ArrayKind, BoolKind, etc.
	Kind()	int;
	// The reflection Type of the value.
	Type()	Type;
	// The address of the value.
	Addr()	Addr;
	// The value itself is the dynamic value of an empty interface.
	Interface()	interface {};
}

func NewValue(e interface{}) Value;

// commonValue fields and functionality for all values

type commonValue struct {
	kind	int;
	typ	Type;
	addr	Addr;
}

func (c *commonValue) Kind() int {
	return c.kind
}

func (c *commonValue) Type() Type {
	return c.typ
}

func (c *commonValue) Addr() Addr {
	return c.addr
}

func (c *commonValue) Interface() interface {} {
	var i interface {};
	switch {
	case c.typ.Kind() == InterfaceKind:
		i = *(*interface{})(c.addr);
	case c.typ.Size() > 8:	// TODO(rsc): how do we know it is 8?
		i = sys.Unreflect(uint64(uintptr(c.addr)), c.typ.String(), true);
	default:
		if uintptr(c.addr) == 0 {
			panicln("reflect: address 0 for", c.typ.String());
		}
		i = sys.Unreflect(uint64(uintptr(*(*Addr)(c.addr))), c.typ.String(), false);
	}
	return i;
}

func newValueAddr(typ Type, addr Addr) Value

type creatorFn func(typ Type, addr Addr) Value


// -- Missing

// MissingValue represents a value whose type is not known. It usually
// indicates an error.
type MissingValue interface {
	Value;
}

type missingValueStruct struct {
	commonValue
}

func missingCreator(typ Type, addr Addr) Value {
	return &missingValueStruct{ commonValue{MissingKind, typ, addr} }
}

// -- Int

// IntValue represents an int value.
type IntValue interface {
	Value;
	Get()	int;	// Get the underlying int.
	Set(int);	// Set the underlying int.
}

type intValueStruct struct {
	commonValue
}

func intCreator(typ Type, addr Addr) Value {
	return &intValueStruct{ commonValue{IntKind, typ, addr} }
}

func (v *intValueStruct) Get() int {
	return *(*int)(v.addr)
}

func (v *intValueStruct) Set(i int) {
	*(*int)(v.addr) = i
}

// -- Int8

// Int8Value represents an int8 value.
type Int8Value interface {
	Value;
	Get()	int8;	// Get the underlying int8.
	Set(int8);	// Set the underlying int8.
}

type int8ValueStruct struct {
	commonValue
}

func int8Creator(typ Type, addr Addr) Value {
	return &int8ValueStruct{ commonValue{Int8Kind, typ, addr} }
}

func (v *int8ValueStruct) Get() int8 {
	return *(*int8)(v.addr)
}

func (v *int8ValueStruct) Set(i int8) {
	*(*int8)(v.addr) = i
}

// -- Int16

// Int16Value represents an int16 value.
type Int16Value interface {
	Value;
	Get()	int16;	// Get the underlying int16.
	Set(int16);	// Set the underlying int16.
}

type int16ValueStruct struct {
	commonValue
}

func int16Creator(typ Type, addr Addr) Value {
	return &int16ValueStruct{ commonValue{Int16Kind, typ, addr} }
}

func (v *int16ValueStruct) Get() int16 {
	return *(*int16)(v.addr)
}

func (v *int16ValueStruct) Set(i int16) {
	*(*int16)(v.addr) = i
}

// -- Int32

// Int32Value represents an int32 value.
type Int32Value interface {
	Value;
	Get()	int32;	// Get the underlying int32.
	Set(int32);	// Set the underlying int32.
}

type int32ValueStruct struct {
	commonValue
}

func int32Creator(typ Type, addr Addr) Value {
	return &int32ValueStruct{ commonValue{Int32Kind, typ, addr} }
}

func (v *int32ValueStruct) Get() int32 {
	return *(*int32)(v.addr)
}

func (v *int32ValueStruct) Set(i int32) {
	*(*int32)(v.addr) = i
}

// -- Int64

// Int64Value represents an int64 value.
type Int64Value interface {
	Value;
	Get()	int64;	// Get the underlying int64.
	Set(int64);	// Set the underlying int64.
}

type int64ValueStruct struct {
	commonValue
}

func int64Creator(typ Type, addr Addr) Value {
	return &int64ValueStruct{ commonValue{Int64Kind, typ, addr} }
}

func (v *int64ValueStruct) Get() int64 {
	return *(*int64)(v.addr)
}

func (v *int64ValueStruct) Set(i int64) {
	*(*int64)(v.addr) = i
}

// -- Uint

// UintValue represents a uint value.
type UintValue interface {
	Value;
	Get()	uint;	// Get the underlying uint.
	Set(uint);	// Set the underlying uint.
}

type uintValueStruct struct {
	commonValue
}

func uintCreator(typ Type, addr Addr) Value {
	return &uintValueStruct{ commonValue{UintKind, typ, addr} }
}

func (v *uintValueStruct) Get() uint {
	return *(*uint)(v.addr)
}

func (v *uintValueStruct) Set(i uint) {
	*(*uint)(v.addr) = i
}

// -- Uint8

// Uint8Value represents a uint8 value.
type Uint8Value interface {
	Value;
	Get()	uint8;	// Get the underlying uint8.
	Set(uint8);	// Set the underlying uint8.
}

type uint8ValueStruct struct {
	commonValue
}

func uint8Creator(typ Type, addr Addr) Value {
	return &uint8ValueStruct{ commonValue{Uint8Kind, typ, addr} }
}

func (v *uint8ValueStruct) Get() uint8 {
	return *(*uint8)(v.addr)
}

func (v *uint8ValueStruct) Set(i uint8) {
	*(*uint8)(v.addr) = i
}

// -- Uint16

// Uint16Value represents a uint16 value.
type Uint16Value interface {
	Value;
	Get()	uint16;	// Get the underlying uint16.
	Set(uint16);	// Set the underlying uint16.
}

type uint16ValueStruct struct {
	commonValue
}

func uint16Creator(typ Type, addr Addr) Value {
	return &uint16ValueStruct{ commonValue{Uint16Kind, typ, addr} }
}

func (v *uint16ValueStruct) Get() uint16 {
	return *(*uint16)(v.addr)
}

func (v *uint16ValueStruct) Set(i uint16) {
	*(*uint16)(v.addr) = i
}

// -- Uint32

// Uint32Value represents a uint32 value.
type Uint32Value interface {
	Value;
	Get()	uint32;	// Get the underlying uint32.
	Set(uint32);	// Set the underlying uint32.
}

type uint32ValueStruct struct {
	commonValue
}

func uint32Creator(typ Type, addr Addr) Value {
	return &uint32ValueStruct{ commonValue{Uint32Kind, typ, addr} }
}

func (v *uint32ValueStruct) Get() uint32 {
	return *(*uint32)(v.addr)
}

func (v *uint32ValueStruct) Set(i uint32) {
	*(*uint32)(v.addr) = i
}

// -- Uint64

// Uint64Value represents a uint64 value.
type Uint64Value interface {
	Value;
	Get()	uint64;	// Get the underlying uint64.
	Set(uint64);	// Set the underlying uint64.
}

type uint64ValueStruct struct {
	commonValue
}

func uint64Creator(typ Type, addr Addr) Value {
	return &uint64ValueStruct{ commonValue{Uint64Kind, typ, addr} }
}

func (v *uint64ValueStruct) Get() uint64 {
	return *(*uint64)(v.addr)
}

func (v *uint64ValueStruct) Set(i uint64) {
	*(*uint64)(v.addr) = i
}

// -- Uintptr

// UintptrValue represents a uintptr value.
type UintptrValue interface {
	Value;
	Get()	uintptr;	// Get the underlying uintptr.
	Set(uintptr);	// Set the underlying uintptr.
}

type uintptrValueStruct struct {
	commonValue
}

func uintptrCreator(typ Type, addr Addr) Value {
	return &uintptrValueStruct{ commonValue{UintptrKind, typ, addr} }
}

func (v *uintptrValueStruct) Get() uintptr {
	return *(*uintptr)(v.addr)
}

func (v *uintptrValueStruct) Set(i uintptr) {
	*(*uintptr)(v.addr) = i
}

// -- Float

// FloatValue represents a float value.
type FloatValue interface {
	Value;
	Get()	float;	// Get the underlying float.
	Set(float);	// Get the underlying float.
}

type floatValueStruct struct {
	commonValue
}

func floatCreator(typ Type, addr Addr) Value {
	return &floatValueStruct{ commonValue{FloatKind, typ, addr} }
}

func (v *floatValueStruct) Get() float {
	return *(*float)(v.addr)
}

func (v *floatValueStruct) Set(f float) {
	*(*float)(v.addr) = f
}

// -- Float32

// Float32Value represents a float32 value.
type Float32Value interface {
	Value;
	Get()	float32;	// Get the underlying float32.
	Set(float32);	// Get the underlying float32.
}

type float32ValueStruct struct {
	commonValue
}

func float32Creator(typ Type, addr Addr) Value {
	return &float32ValueStruct{ commonValue{Float32Kind, typ, addr} }
}

func (v *float32ValueStruct) Get() float32 {
	return *(*float32)(v.addr)
}

func (v *float32ValueStruct) Set(f float32) {
	*(*float32)(v.addr) = f
}

// -- Float64

// Float64Value represents a float64 value.
type Float64Value interface {
	Value;
	Get()	float64;	// Get the underlying float64.
	Set(float64);	// Get the underlying float64.
}

type float64ValueStruct struct {
	commonValue
}

func float64Creator(typ Type, addr Addr) Value {
	return &float64ValueStruct{ commonValue{Float64Kind, typ, addr} }
}

func (v *float64ValueStruct) Get() float64 {
	return *(*float64)(v.addr)
}

func (v *float64ValueStruct) Set(f float64) {
	*(*float64)(v.addr) = f
}

// -- String

// StringValue represents a string value.
type StringValue interface {
	Value;
	Get()	string;	// Get the underlying string value.
	Set(string);	// Set the underlying string value.
}

type stringValueStruct struct {
	commonValue
}

func stringCreator(typ Type, addr Addr) Value {
	return &stringValueStruct{ commonValue{StringKind, typ, addr} }
}

func (v *stringValueStruct) Get() string {
	return *(*string)(v.addr)
}

func (v *stringValueStruct) Set(s string) {
	*(*string)(v.addr) = s
}

// -- Bool

// BoolValue represents a bool value.
type BoolValue interface {
	Value;
	Get()	bool;	// Get the underlying bool value.
	Set(bool);	// Set the underlying bool value.
}

type boolValueStruct struct {
	commonValue
}

func boolCreator(typ Type, addr Addr) Value {
	return &boolValueStruct{ commonValue{BoolKind, typ, addr} }
}

func (v *boolValueStruct) Get() bool {
	return *(*bool)(v.addr)
}

func (v *boolValueStruct) Set(b bool) {
	*(*bool)(v.addr) = b
}

// -- Pointer

// PtrValue represents a pointer value.
type PtrValue interface {
	Value;
	Sub()	Value;	// The Value pointed to.
	Get()	Addr;	// Get the address stored in the pointer.
	SetSub(Value);	// Set the the pointed-to Value.
}

type ptrValueStruct struct {
	commonValue
}

func (v *ptrValueStruct) Get() Addr {
	return *(*Addr)(v.addr)
}

func (v *ptrValueStruct) Sub() Value {
	return newValueAddr(v.typ.(PtrType).Sub(), v.Get());
}

func (v *ptrValueStruct) SetSub(subv Value) {
	a := v.typ.(PtrType).Sub();
	b := subv.Type();
	if !equalType(a, b) {
		panicln("reflect: incompatible types in PtrValue.SetSub:",
			a.String(), b.String());
	}
	*(*Addr)(v.addr) = subv.Addr();
}

func ptrCreator(typ Type, addr Addr) Value {
	return &ptrValueStruct{ commonValue{PtrKind, typ, addr} };
}

// -- Array
// Slices and arrays are represented by the same interface.

// ArrayValue represents an array or slice value.
type ArrayValue interface {
	Value;
	IsSlice()	bool;	// Is this a slice (true) or array (false)?
	Len()	int;	// The length of the array/slice.
	Cap() int;	// The capacity of the array/slice (==Len() for arrays).
	Elem(i int)	Value;	// The Value of the i'th element.
	SetLen(len int);	// Set the length; slice only.
	Set(src ArrayValue);	// Set the underlying Value; slice only for src and dest both.
	CopyFrom(src ArrayValue, n int)	// Copy the elements from src; lengths must match.
}

func copyArray(dst ArrayValue, src ArrayValue, n int);

/*
	Run-time representation of slices looks like this:
		struct	Slice {
			byte*	array;		// actual data
			uint32	nel;		// number of elements
			uint32	cap;
		};
*/
type runtimeSlice struct {
	data	Addr;
	len	uint32;
	cap	uint32;
}

type sliceValueStruct struct {
	commonValue;
	elemtype	Type;
	elemsize	int;
	slice *runtimeSlice;
}

func (v *sliceValueStruct) IsSlice() bool {
	return true
}

func (v *sliceValueStruct) Len() int {
	return int(v.slice.len);
}

func (v *sliceValueStruct) Cap() int {
	return int(v.slice.cap);
}

func (v *sliceValueStruct) SetLen(len int) {
	if len > v.Cap() {
		panicln("reflect: sliceValueStruct.SetLen", len, v.Cap());
	}
	v.slice.len = uint32(len);
}

func (v *sliceValueStruct) Set(src ArrayValue) {
	if !src.IsSlice() {
		panic("can't set slice from array");
	}
	s := src.(*sliceValueStruct);
	if !equalType(v.typ, s.typ) {
		panicln("incompatible types in ArrayValue.Set()");
	}
	*v.slice = *s.slice;
}

func (v *sliceValueStruct) Elem(i int) Value {
	data_uint := uintptr(v.slice.data) + uintptr(i * v.elemsize);
	return newValueAddr(v.elemtype, Addr(data_uint));
}

func (v *sliceValueStruct) CopyFrom(src ArrayValue, n int) {
	copyArray(v, src, n);
}

type arrayValueStruct struct {
	commonValue;
	elemtype	Type;
	elemsize	int;
	len	int;
}

func (v *arrayValueStruct) IsSlice() bool {
	return false
}

func (v *arrayValueStruct) Len() int {
	return v.len
}

func (v *arrayValueStruct) Cap() int {
	return v.len
}

func (v *arrayValueStruct) SetLen(len int) {
	panicln("can't set len of array");
}

func (v *arrayValueStruct) Set(src ArrayValue) {
	panicln("can't set array");
}

func (v *arrayValueStruct) Elem(i int) Value {
	data_uint := uintptr(v.addr) + uintptr(i * v.elemsize);
	return newValueAddr(v.elemtype, Addr(data_uint));
	return nil
}

func (v *arrayValueStruct) CopyFrom(src ArrayValue, n int) {
	copyArray(v, src, n);
}

func arrayCreator(typ Type, addr Addr) Value {
	arraytype := typ.(ArrayType);
	if arraytype.IsSlice() {
		v := new(sliceValueStruct);
		v.kind = ArrayKind;
		v.addr = addr;
		v.typ = typ;
		v.elemtype = arraytype.Elem();
		v.elemsize = v.elemtype.Size();
		v.slice = (*runtimeSlice)(addr);
		return v;
	}
	v := new(arrayValueStruct);
	v.kind = ArrayKind;
	v.addr = addr;
	v.typ = typ;
	v.elemtype = arraytype.Elem();
	v.elemsize = v.elemtype.Size();
	v.len = arraytype.Len();
	return v;
}

// -- Map	TODO: finish and test

// MapValue represents a map value.
// Its implementation is incomplete.
type MapValue interface {
	Value;
	Len()	int;	// The number of elements; currently always returns 0.
	Elem(key Value)	Value;	// The value indexed by key; unimplemented.
}

type mapValueStruct struct {
	commonValue
}

func mapCreator(typ Type, addr Addr) Value {
	return &mapValueStruct{ commonValue{MapKind, typ, addr} }
}

func (v *mapValueStruct) Len() int {
	return 0	// TODO: probably want this to be dynamic
}

func (v *mapValueStruct) Elem(key Value) Value {
	panic("map value element");
	return nil
}

// -- Chan

// ChanValue represents a chan value.
// Its implementation is incomplete.
type ChanValue interface {
	Value;
}

type chanValueStruct struct {
	commonValue
}

func chanCreator(typ Type, addr Addr) Value {
	return &chanValueStruct{ commonValue{ChanKind, typ, addr} }
}

// -- Struct

// StructValue represents a struct value.
type StructValue interface {
	Value;
	Len()	int;	// The number of fields.
	Field(i int)	Value;	// The Value of field i.
}

type structValueStruct struct {
	commonValue;
	field	[]Value;
}

func (v *structValueStruct) Len() int {
	return len(v.field)
}

func (v *structValueStruct) Field(i int) Value {
	return v.field[i]
}

func structCreator(typ Type, addr Addr) Value {
	t := typ.(StructType);
	nfield := t.Len();
	v := &structValueStruct{ commonValue{StructKind, typ, addr}, make([]Value, nfield) };
	for i := 0; i < nfield; i++ {
		name, ftype, str, offset := t.Field(i);
		addr_uint := uintptr(addr) + uintptr(offset);
		v.field[i] = newValueAddr(ftype, Addr(addr_uint));
	}
	v.typ = typ;
	return v;
}

// -- Interface

// InterfaceValue represents an interface value.
type InterfaceValue interface {
	Value;
	Get()	interface {};	// Get the underlying interface{} value.
	Value() Value;
}

type interfaceValueStruct struct {
	commonValue
}

func (v *interfaceValueStruct) Get() interface{} {
	return *(*interface{})(v.addr)
}

func (v *interfaceValueStruct) Value() Value {
	i := v.Get();
	if i == nil {
		return nil;
	}
	return NewValue(i);
}

func interfaceCreator(typ Type, addr Addr) Value {
	return &interfaceValueStruct{ commonValue{InterfaceKind, typ, addr} }
}

// -- Func


// FuncValue represents a func value.
// Its implementation is incomplete.
type FuncValue interface {
	Value;
	Get()	Addr;	// The address of the function.
}

type funcValueStruct struct {
	commonValue
}

func (v *funcValueStruct) Get() Addr {
	return *(*Addr)(v.addr)
}

func funcCreator(typ Type, addr Addr) Value {
	return &funcValueStruct{ commonValue{FuncKind, typ, addr} }
}

var creator = map[int] creatorFn {
	MissingKind : missingCreator,
	IntKind : intCreator,
	Int8Kind : int8Creator,
	Int16Kind : int16Creator,
	Int32Kind : int32Creator,
	Int64Kind : int64Creator,
	UintKind : uintCreator,
	Uint8Kind : uint8Creator,
	Uint16Kind : uint16Creator,
	Uint32Kind : uint32Creator,
	Uint64Kind : uint64Creator,
	UintptrKind : uintptrCreator,
	FloatKind : floatCreator,
	Float32Kind : float32Creator,
	Float64Kind : float64Creator,
	StringKind : stringCreator,
	BoolKind : boolCreator,
	PtrKind : ptrCreator,
	ArrayKind : arrayCreator,
	MapKind : mapCreator,
	ChanKind : chanCreator,
	StructKind : structCreator,
	InterfaceKind : interfaceCreator,
	FuncKind : funcCreator,
}

var typecache = make(map[string] Type);

func newValueAddr(typ Type, addr Addr) Value {
	c, ok := creator[typ.Kind()];
	if !ok {
		panicln("no creator for type" , typ.Kind());
	}
	return c(typ, addr);
}

// NewInitValue creates a new, zero-initialized Value for the specified Type.
func NewInitValue(typ Type) Value {
	// Some values cannot be made this way.
	switch typ.Kind() {
	case ArrayKind:
		if typ.(ArrayType).IsSlice() {
			return nil
		}
	}
	size := typ.Size();
	if size == 0 {
		size = 1;
	}
	data := make([]uint8, size);
	return newValueAddr(typ, Addr(&data[0]));
}

// NewSliceValue creates a new, zero-initialized slice value (ArrayValue) for the specified
// slice type (ArrayType), length, and capacity.
func NewSliceValue(typ ArrayType, len, cap int) ArrayValue {
	if !typ.IsSlice() {
		return nil
	}

	array := new(runtimeSlice);
	size := typ.Elem().Size() * cap;
	if size == 0 {
		size = 1;
	}
	data := make([]uint8, size);
	array.data = Addr(&data[0]);
	array.len = uint32(len);
	array.cap = uint32(cap);

	return newValueAddr(typ, Addr(array)).(ArrayValue);
}

// Works on both slices and arrays
func copyArray(dst ArrayValue, src ArrayValue, n int) {
	if n == 0 {
		return
	}
	dt := dst.Type().(ArrayType).Elem();
	st := src.Type().(ArrayType).Elem();
	if !equalType(dt, st) {
		panicln("reflect: incompatible types in CopyArray:",
			dt.String(), st.String());
	}
	if n < 0 || n > dst.Len() || n > src.Len() {
		panicln("reflect: CopyArray: invalid count", n);
	}
	dstp := uintptr(dst.Elem(0).Addr());
	srcp := uintptr(src.Elem(0).Addr());
	end := uintptr(n)*uintptr(dt.Size());
	if end % 8 == 0 {
		for i := uintptr(0); i < end; i += 8{
			di := Addr(dstp + i);
			si := Addr(srcp + i);
			*(*uint64)(di) = *(*uint64)(si);
		}
	} else {
		for i := uintptr(0); i < end; i++ {
			di := Addr(dstp + i);
			si := Addr(srcp + i);
			*(*byte)(di) = *(*byte)(si);
		}
	}
}

// NewValue creates a new Value from the interface{} object provided.
func NewValue(e interface {}) Value {
	value, typestring, indir := sys.Reflect(e);
	typ, ok := typecache[typestring];
	if !ok {
		typ = ParseTypeString("", typestring);
		typecache[typestring] = typ;
	}

	if indir {
		// Content of interface is a pointer.
		return newValueAddr(typ, Addr(uintptr(value)));
	}

	// Content of interface is a value;
	// need a permanent copy to take its address.
	ap := new(uint64);
	*ap = value;
	return newValueAddr(typ, Addr(ap));
}

// Indirect indirects one level through a value, if it is a pointer.
// If not a pointer, the value is returned unchanged.
// Useful when walking arbitrary data structures.
func Indirect(v Value) Value {
	if v.Kind() == PtrKind {
		p := v.(PtrValue);
		if p.Get() == nil {
			return nil
		}
		v = p.Sub()
	}
	return v
}
