// 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.
// Formatting of reflection types and values for debugging.
// Not defined as methods so they do not need to be linked into most binaries;
// the functions are not used by the library itself, only in tests.

package reflect

import (
	"reflect";
	"strconv";
)

func typeToString(typ Type, expand bool) string
func valueToString(val Value) string

func doubleQuote(s string) string {
	out := "\"";
	for i := 0; i < len(s); i++ {
		c := s[i];
		switch c {
		case '\n':
			out += `\n`;
		case '\t':
			out += `\t`;
		case '\x00':
			out += `\x00`;
		case '"':
			out += `\"`;
		case '\\':
			out += `\\`;
		default:
			out += string(c);
		}
	}
	out += "\"";
	return out;
}

type hasFields interface {
	Field(i int)	(name string, typ Type, tag string, offset int);
	Len()	int;
}

func typeFieldsToString(t hasFields, sep string, iface bool) string {
	var str string;
	for i := 0; i < t.Len(); i++ {
		str1, typ, tag, offset := t.Field(i);
		if str1 != "" {
			str1 += " "
		}
		str2 := typeToString(typ, false);
		if iface && str2[0:4] == "func" {
			str2 = str2[4:len(str2)]
		}
		str1 += str2;
		if tag != "" {
			str1 += " " + doubleQuote(tag);
		}
		if i < t.Len() - 1 {
			str1 += sep + " ";
		}
		str += str1;
	}
	return str;
}

// typeToString returns a textual representation of typ.  The expand
// flag specifies whether to expand the contents of type names; if false,
// the name itself is used as the representation.
// Meant for debugging only; typ.String() serves for most purposes.
func typeToString(typ Type, expand bool) string {
	var str string;
	if name := typ.Name(); !expand && name != "" {
		return name
	}
	switch(typ.Kind()) {
	case MissingKind:
		return "$missing$";
	case IntKind, Int8Kind, Int16Kind, Int32Kind, Int64Kind,
	     UintKind, Uint8Kind, Uint16Kind, Uint32Kind, Uint64Kind,
	     FloatKind, Float32Kind, Float64Kind,
	     StringKind,
	     DotDotDotKind:
		return typ.Name();
	case PtrKind:
		p := typ.(PtrType);
		return "*" + typeToString(p.Sub(), false);
	case ArrayKind:
		a := typ.(ArrayType);
		if a.IsSlice() {
			str = "[]"
		} else {
			str = "[" + strconv.Itoa64(int64(a.Len())) +  "]"
		}
		return str + typeToString(a.Elem(), false);
	case MapKind:
		m := typ.(MapType);
		str = "map[" + typeToString(m.Key(), false) + "]";
		return str + typeToString(m.Elem(), false);
	case ChanKind:
		c := typ.(ChanType);
		switch c.Dir() {
		case RecvDir:
			str = "<-chan";
		case SendDir:
			str = "chan<-";
		case BothDir:
			str = "chan";
		default:
			panicln("reflect.typeToString: unknown chan direction");
		}
		return str + typeToString(c.Elem(), false);
	case StructKind:
		return "struct{" + typeFieldsToString(typ.(StructType), ";", false) + "}";
	case InterfaceKind:
		return "interface{" + typeFieldsToString(typ.(InterfaceType), ";", true) + "}";
	case FuncKind:
		f := typ.(FuncType);
		str = "func(" + typeFieldsToString(f.In(), ",", false) + ")";
		if f.Out() != nil {
			str += "(" + typeFieldsToString(f.Out(), ",", false) + ")";
		}
		return str;
	default:
		panicln("reflect.typeToString: can't print type ", typ.Kind());
	}
	return "reflect.typeToString: can't happen";
}

// TODO: want an unsigned one too
func integer(v int64) string {
	return strconv.Itoa64(v);
}

// valueToString returns a textual representation of the reflection value val.
// For debugging only.
func valueToString(val Value) string {
	var str string;
	typ := val.Type();
	switch(val.Kind()) {
	case MissingKind:
		return "missing";
	case IntKind:
		return integer(int64(val.(IntValue).Get()));
	case Int8Kind:
		return integer(int64(val.(Int8Value).Get()));
	case Int16Kind:
		return integer(int64(val.(Int16Value).Get()));
	case Int32Kind:
		return integer(int64(val.(Int32Value).Get()));
	case Int64Kind:
		return integer(int64(val.(Int64Value).Get()));
	case UintKind:
		return integer(int64(val.(UintValue).Get()));
	case Uint8Kind:
		return integer(int64(val.(Uint8Value).Get()));
	case Uint16Kind:
		return integer(int64(val.(Uint16Value).Get()));
	case Uint32Kind:
		return integer(int64(val.(Uint32Value).Get()));
	case Uint64Kind:
		return integer(int64(val.(Uint64Value).Get()));
	case FloatKind:
		if strconv.FloatSize == 32 {
			return strconv.Ftoa32(float32(val.(FloatValue).Get()), 'g', -1);
		} else {
			return strconv.Ftoa64(float64(val.(FloatValue).Get()), 'g', -1);
		}
	case Float32Kind:
		return strconv.Ftoa32(val.(Float32Value).Get(), 'g', -1);
	case Float64Kind:
		return strconv.Ftoa64(val.(Float64Value).Get(), 'g', -1);
	case StringKind:
		return val.(StringValue).Get();
	case BoolKind:
		if val.(BoolValue).Get() {
			return "true"
		} else {
			return "false"
		}
	case PtrKind:
		v := val.(PtrValue);
		return typeToString(typ, false) + "(" + integer(int64(uintptr(v.Get()))) + ")";
	case ArrayKind:
		t := typ.(ArrayType);
		v := val.(ArrayValue);
		str += typeToString(t, false);
		str += "{";
		for i := 0; i < v.Len(); i++ {
			if i > 0 {
				str += ", "
			}
			str += valueToString(v.Elem(i));
		}
		str += "}";
		return str;
	case MapKind:
		t := typ.(MapType);
		v := val.(MapValue);
		str = typeToString(t, false);
		str += "{";
		str += "<can't iterate on maps>";
		str += "}";
		return str;
	case ChanKind:
		str = typeToString(typ, false);
		return str;
	case StructKind:
		t := typ.(StructType);
		v := val.(StructValue);
		str += typeToString(t, false);
		str += "{";
		for i := 0; i < v.Len(); i++ {
			if i > 0 {
				str += ", "
			}
			str += valueToString(v.Field(i));
		}
		str += "}";
		return str;
	case InterfaceKind:
		return "can't print interfaces yet";
	case FuncKind:
		v := val.(FuncValue);
		return typeToString(typ, false) + "(" + integer(int64(uintptr(v.Get()))) + ")";
	default:
		panicln("reflect.valueToString: can't print type ", val.Kind());
	}
	return "reflect.valueToString: can't happen";
}
