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

import (
	"log";
	"go/token";
	"reflect";
)

/*
 * Type bridging
 */

var (
	evalTypes   = make(map[reflect.Type] Type);
	nativeTypes = make(map[Type] reflect.Type);
)

// TypeFromNative converts a regular Go type into a the corresponding
// interpreter Type.
func TypeFromNative(t reflect.Type) Type {
	if et, ok := evalTypes[t]; ok {
		return et;
	}

	var nt *NamedType;
	if t.Name() != "" {
		name := t.PkgPath() + "·" + t.Name();
		nt = &NamedType{token.Position{}, name, nil, true, make(map[string] Method)};
		evalTypes[t] = nt;
	}

	var et Type;
	switch t := t.(type) {
	case *reflect.BoolType:
		et = BoolType;
	case *reflect.Float32Type:
		et = Float32Type;
	case *reflect.Float64Type:
		et = Float64Type;
	case *reflect.FloatType:
		et = FloatType;
	case *reflect.Int16Type:
		et = Int16Type;
	case *reflect.Int32Type:
		et = Int32Type;
	case *reflect.Int64Type:
		et = Int64Type;
	case *reflect.Int8Type:
		et = Int8Type;
	case *reflect.IntType:
		et = IntType;
	case *reflect.StringType:
		et = StringType;
	case *reflect.Uint16Type:
		et = Uint16Type;
	case *reflect.Uint32Type:
		et = Uint32Type;
	case *reflect.Uint64Type:
		et = Uint64Type;
	case *reflect.Uint8Type:
		et = Uint8Type;
	case *reflect.UintType:
		et = UintType;
	case *reflect.UintptrType:
		et = UintptrType;

	case *reflect.ArrayType:
		et = NewArrayType(int64(t.Len()), TypeFromNative(t.Elem()));
	case *reflect.ChanType:
		log.Crashf("%T not implemented", t);
	case *reflect.FuncType:
		nin := t.NumIn();
		// Variadic functions have DotDotDotType at the end
		varidic := false;
		if nin > 0 {
			if _, ok := t.In(nin - 1).(*reflect.DotDotDotType); ok {
				varidic = true;
				nin--;
			}
		}
		in := make([]Type, nin);
		for i := range in {
			in[i] = TypeFromNative(t.In(i));
		}
		out := make([]Type, t.NumOut());
		for i := range out {
			out[i] = TypeFromNative(t.Out(i));
		}
		et = NewFuncType(in, varidic, out);
	case *reflect.InterfaceType:
		log.Crashf("%T not implemented", t);
	case *reflect.MapType:
		log.Crashf("%T not implemented", t);
	case *reflect.PtrType:
		et = NewPtrType(TypeFromNative(t.Elem()));
	case *reflect.SliceType:
		et = NewSliceType(TypeFromNative(t.Elem()));
	case *reflect.StructType:
		n := t.NumField();
		fields := make([]StructField, n);
		for i := 0; i < n; i++ {
			sf := t.Field(i);
			// TODO(austin) What to do about private fields?
			fields[i].Name = sf.Name;
			fields[i].Type = TypeFromNative(sf.Type);
			fields[i].Anonymous = sf.Anonymous;
		}
		et = NewStructType(fields);
	case *reflect.UnsafePointerType:
		log.Crashf("%T not implemented", t);
	default:
		log.Crashf("unexpected reflect.Type: %T", t);
	}

	if nt != nil {
		nt.Complete(et);
		et = nt;
	}

	nativeTypes[et] = t;
	evalTypes[t] = et;

	return et;
}

// TypeOfNative returns the interpreter Type of a regular Go value.
func TypeOfNative(v interface {}) Type {
	return TypeFromNative(reflect.Typeof(v));
}

/*
 * Function bridging
 */

type nativeFunc struct {
	fn func([]Value, []Value);
	in, out int;
}

func (f *nativeFunc) NewFrame() *Frame {
	vars := make([]Value, f.in + f.out);
	return &Frame{nil, vars};
}

func (f *nativeFunc) Call(t *Thread) {
	f.fn(t.f.Vars[0:f.in], t.f.Vars[f.in:f.in+f.out]);
}

// FuncFromNative creates an interpreter function from a native
// function that takes its in and out arguments as slices of
// interpreter Value's.  While somewhat inconvenient, this avoids
// value marshalling.
func FuncFromNative(fn func([]Value, []Value), t *FuncType) FuncValue {
	return &funcV{&nativeFunc{fn, len(t.In), len(t.Out)}};
}

// FuncFromNativeTyped is like FuncFromNative, but constructs the
// function type from a function pointer using reflection.  Typically,
// the type will be given as a nil pointer to a function with the
// desired signature.
func FuncFromNativeTyped(fn func([]Value, []Value), t interface{}) (*FuncType, FuncValue) {
	ft := TypeOfNative(t).(*FuncType);
	return ft, FuncFromNative(fn, ft);
}
