// 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 (
	"bignum"
	"flag"
	"fmt"
	"log"
	"os"
	"reflect"
	"testing"
)

// Print each statement or expression before parsing it
var noisy = false

func init() { flag.BoolVar(&noisy, "noisy", false, "chatter during eval tests") }

/*
 * Generic statement/expression test framework
 */

type test []job

type job struct {
	code  string
	cerr  string
	rterr string
	val   Value
	noval bool
}

func runTests(t *testing.T, baseName string, tests []test) {
	for i, test := range tests {
		name := fmt.Sprintf("%s[%d]", baseName, i)
		test.run(t, name)
	}
}

func (a test) run(t *testing.T, name string) {
	w := newTestWorld()
	for _, j := range a {
		src := j.code
		if noisy {
			println("code:", src)
		}

		code, err := w.Compile(src)
		if err != nil {
			if j.cerr == "" {
				t.Errorf("%s: Compile %s: %v", name, src, err)
				break
			}
			if !match(t, err, j.cerr) {
				t.Errorf("%s: Compile %s = error %s; want %v", name, src, err, j.cerr)
				break
			}
			continue
		}
		if j.cerr != "" {
			t.Errorf("%s: Compile %s succeeded; want %s", name, src, j.cerr)
			break
		}

		val, err := code.Run()
		if err != nil {
			if j.rterr == "" {
				t.Errorf("%s: Run %s: %v", name, src, err)
				break
			}
			if !match(t, err, j.rterr) {
				t.Errorf("%s: Run %s = error %s; want %v", name, src, err, j.rterr)
				break
			}
			continue
		}
		if j.rterr != "" {
			t.Errorf("%s: Run %s succeeded; want %s", name, src, j.rterr)
			break
		}

		if !j.noval && !reflect.DeepEqual(val, j.val) {
			t.Errorf("%s: Run %s = %T(%v) want %T(%v)", name, src, val, val, j.val, j.val)
		}
	}
}

func match(t *testing.T, err os.Error, pat string) bool {
	ok, errstr := testing.MatchString(pat, err.String())
	if errstr != "" {
		t.Fatalf("compile regexp %s: %v", pat, errstr)
	}
	return ok
}


/*
 * Test constructors
 */

// Expression compile error
func CErr(expr string, cerr string) test { return test([]job{job{code: expr, cerr: cerr}}) }

// Expression runtime error
func RErr(expr string, rterr string) test { return test([]job{job{code: expr, rterr: rterr}}) }

// Expression value
func Val(expr string, val interface{}) test {
	return test([]job{job{code: expr, val: toValue(val)}})
}

// Statement runs without error
func Run(stmts string) test { return test([]job{job{code: stmts, noval: true}}) }

// Two statements without error.
// TODO(rsc): Should be possible with Run but the parser
// won't let us do both top-level and non-top-level statements.
func Run2(stmt1, stmt2 string) test {
	return test([]job{job{code: stmt1, noval: true}, job{code: stmt2, noval: true}})
}

// Statement runs and test one expression's value
func Val1(stmts string, expr1 string, val1 interface{}) test {
	return test([]job{
		job{code: stmts, noval: true},
		job{code: expr1, val: toValue(val1)},
	})
}

// Statement runs and test two expressions' values
func Val2(stmts string, expr1 string, val1 interface{}, expr2 string, val2 interface{}) test {
	return test([]job{
		job{code: stmts, noval: true},
		job{code: expr1, val: toValue(val1)},
		job{code: expr2, val: toValue(val2)},
	})
}

/*
 * Value constructors
 */

type vstruct []interface{}

type varray []interface{}

type vslice struct {
	arr      varray
	len, cap int
}

func toValue(val interface{}) Value {
	switch val := val.(type) {
	case bool:
		r := boolV(val)
		return &r
	case uint8:
		r := uint8V(val)
		return &r
	case uint:
		r := uintV(val)
		return &r
	case int:
		r := intV(val)
		return &r
	case *bignum.Integer:
		return &idealIntV{val}
	case float:
		r := floatV(val)
		return &r
	case *bignum.Rational:
		return &idealFloatV{val}
	case string:
		r := stringV(val)
		return &r
	case vstruct:
		elems := make([]Value, len(val))
		for i, e := range val {
			elems[i] = toValue(e)
		}
		r := structV(elems)
		return &r
	case varray:
		elems := make([]Value, len(val))
		for i, e := range val {
			elems[i] = toValue(e)
		}
		r := arrayV(elems)
		return &r
	case vslice:
		return &sliceV{Slice{toValue(val.arr).(ArrayValue), int64(val.len), int64(val.cap)}}
	case Func:
		return &funcV{val}
	}
	log.Crashf("toValue(%T) not implemented", val)
	panic()
}

/*
 * Default test scope
 */

type testFunc struct{}

func (*testFunc) NewFrame() *Frame { return &Frame{nil, &[2]Value{}} }

func (*testFunc) Call(t *Thread) {
	n := t.f.Vars[0].(IntValue).Get(t)

	res := n + 1

	t.f.Vars[1].(IntValue).Set(t, res)
}

type oneTwoFunc struct{}

func (*oneTwoFunc) NewFrame() *Frame { return &Frame{nil, &[2]Value{}} }

func (*oneTwoFunc) Call(t *Thread) {
	t.f.Vars[0].(IntValue).Set(t, 1)
	t.f.Vars[1].(IntValue).Set(t, 2)
}

type voidFunc struct{}

func (*voidFunc) NewFrame() *Frame { return &Frame{nil, []Value{}} }

func (*voidFunc) Call(t *Thread) {}

func newTestWorld() *World {
	w := NewWorld()

	def := func(name string, t Type, val interface{}) { w.DefineVar(name, t, toValue(val)) }

	w.DefineConst("c", IdealIntType, toValue(bignum.Int(1)))
	def("i", IntType, 1)
	def("i2", IntType, 2)
	def("u", UintType, uint(1))
	def("f", FloatType, 1.0)
	def("s", StringType, "abc")
	def("t", NewStructType([]StructField{StructField{"a", IntType, false}}), vstruct{1})
	def("ai", NewArrayType(2, IntType), varray{1, 2})
	def("aai", NewArrayType(2, NewArrayType(2, IntType)), varray{varray{1, 2}, varray{3, 4}})
	def("aai2", NewArrayType(2, NewArrayType(2, IntType)), varray{varray{5, 6}, varray{7, 8}})
	def("fn", NewFuncType([]Type{IntType}, false, []Type{IntType}), &testFunc{})
	def("oneTwo", NewFuncType([]Type{}, false, []Type{IntType, IntType}), &oneTwoFunc{})
	def("void", NewFuncType([]Type{}, false, []Type{}), &voidFunc{})
	def("sli", NewSliceType(IntType), vslice{varray{1, 2, 3}, 2, 3})

	return w
}
