// Copyright 2010 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 try contains the executable part of the gotry command.
// It is not intended for general use.
package try

import (
	"fmt"
	"io"
	"os"
	"reflect"
	"unicode"
)

var output io.Writer = os.Stdout // redirected when testing

// Main is called directly from the gotry-generated Go source file to perform
// the evaluations.
func Main(pkg, firstArg string, functions map[string]interface{}, args []interface{}) {
	switch len(args) {
	case 0:
		// Nothing to do.
	case 1:
		// Compiler has already evaluated the expression; just print the result.
		printSlice(firstArg, args)
	default:
		// See if methods satisfy the expressions.
		tryMethods(pkg, firstArg, args)
		// See if functions satisfy the expressions.
		for name, fn := range functions {
			tryFunction(pkg, name, fn, args)
		}
	}
}

// printSlice prints the zeroth element of the args slice, which should (by construction)
// itself be a slice of interface{}.
func printSlice(firstArg string, args []interface{}) {
	// Args should be length 1 and a slice.
	if len(args) != 1 {
		return
	}
	arg, ok := args[0].([]interface{})
	if !ok {
		return
	}
	fmt.Fprintf(output, "%s = ", firstArg)
	if len(arg) > 1 {
		fmt.Fprint(output, "(")
	}
	for i, a := range arg {
		if i > 0 {
			fmt.Fprint(output, ", ")
		}
		fmt.Fprintf(output, "%#v", a)
	}
	if len(arg) > 1 {
		fmt.Fprint(output, ")")
	}
	fmt.Fprint(output, "\n")
}

// tryMethods sees if the zeroth arg has methods, and if so treats them as potential
// functions to satisfy the remaining arguments.
func tryMethods(pkg, firstArg string, args []interface{}) {
	defer func() { recover() }()
	// Is the first argument something with methods?
	v := reflect.ValueOf(args[0])
	typ := v.Type()
	if typ.NumMethod() == 0 {
		return
	}
	for i := 0; i < typ.NumMethod(); i++ {
		if unicode.IsUpper(int(typ.Method(i).Name[0])) {
			tryMethod(pkg, firstArg, typ.Method(i), args)
		}
	}
}

// tryMethod converts a method to a function for tryOneFunction.
func tryMethod(pkg, firstArg string, method reflect.Method, args []interface{}) {
	rfn := method.Func
	typ := method.Type
	name := method.Name
	tryOneFunction(pkg, firstArg, name, typ, rfn, args)
}

// tryFunction sees if fn satisfies the arguments.
func tryFunction(pkg, name string, fn interface{}, args []interface{}) {
	defer func() { recover() }()
	rfn := reflect.ValueOf(fn)
	typ := rfn.Type()
	tryOneFunction(pkg, "", name, typ, rfn, args)
}

// tryOneFunction is the common code for tryMethod and tryFunction.
func tryOneFunction(pkg, firstArg, name string, typ reflect.Type, rfn reflect.Value, args []interface{}) {
	// Any results?
	if typ.NumOut() == 0 {
		return // Nothing to do.
	}
	// Right number of arguments + results?
	if typ.NumIn()+typ.NumOut() != len(args) {
		return
	}
	// Right argument and result types?
	for i, a := range args {
		if i < typ.NumIn() {
			if !compatible(a, typ.In(i)) {
				return
			}
		} else {
			if !compatible(a, typ.Out(i-typ.NumIn())) {
				return
			}
		}
	}
	// Build the call args.
	argsVal := make([]reflect.Value, typ.NumIn()+typ.NumOut())
	for i, a := range args {
		argsVal[i] = reflect.ValueOf(a)
	}
	// Call the function and see if the results are as expected.
	resultVal := rfn.Call(argsVal[:typ.NumIn()])
	for i, v := range resultVal {
		if !reflect.DeepEqual(v.Interface(), args[i+typ.NumIn()]) {
			return
		}
	}
	// Present the result including a godoc command to get more information.
	firstIndex := 0
	if firstArg != "" {
		fmt.Fprintf(output, "%s.%s(", firstArg, name)
		firstIndex = 1
	} else {
		fmt.Fprintf(output, "%s.%s(", pkg, name)
	}
	for i := firstIndex; i < typ.NumIn(); i++ {
		if i > firstIndex {
			fmt.Fprint(output, ", ")
		}
		fmt.Fprintf(output, "%#v", args[i])
	}
	fmt.Fprint(output, ") = ")
	if typ.NumOut() > 1 {
		fmt.Fprint(output, "(")
	}
	for i := 0; i < typ.NumOut(); i++ {
		if i > 0 {
			fmt.Fprint(output, ", ")
		}
		fmt.Fprintf(output, "%#v", resultVal[i].Interface())
	}
	if typ.NumOut() > 1 {
		fmt.Fprint(output, ")")
	}
	fmt.Fprintf(output, "  // godoc %s %s\n", pkg, name)
}

// compatible reports whether the argument is compatible with the type.
func compatible(arg interface{}, typ reflect.Type) bool {
	if reflect.TypeOf(arg) == typ {
		return true
	}
	if arg == nil {
		// nil is OK if the type is an interface.
		if typ.Kind() == reflect.Interface {
			return true
		}
	}
	return false
}
