package container

import (
	"errors"
	"fmt"
	"reflect"
)

type NewTransactionBroker struct {
	// 调用器
	caller Caller
	// 会话
	sessionContext *SessionContext
}

func (broker *NewTransactionBroker) Call(in []reflect.Value) []reflect.Value {
	// 从接口获取方法,Receiver不算作入参
	if len(in) < 1 {
		// Todo Log
		return []reflect.Value{reflect.ValueOf(errors.New(fmt.Sprintf("参数长度错误!")))}
	}
	firstParameter := in[0]
	switch firstParameter.Kind() {
	case reflect.Ptr:
		if firstParameter.Type() != RequestContextType {
			// Todo Log
			return []reflect.Value{reflect.ValueOf(errors.New(fmt.Sprintf("第一个参数类型不正确!")))}
		}
		if firstParameter.IsNil() {
			// Todo Log
			return []reflect.Value{reflect.ValueOf(errors.New(fmt.Sprintf("第一个参数必须赋值!")))}
		}
		break
	case reflect.Invalid:
		return []reflect.Value{reflect.ValueOf(errors.New(fmt.Sprintf("第一个参数不能为空!")))}
		break
	default:
		// Todo Log
		return []reflect.Value{reflect.ValueOf(errors.New(fmt.Sprintf("第一个参数类型错误!")))}
	}
	requestContext := firstParameter.Interface().(*RequestContext)
	if requestContext.session != nil {
		// Todo Log
		return []reflect.Value{reflect.ValueOf(errors.New(fmt.Sprintf("上下文的会话应当为空!")))}
	}
	transactionHandler, err := broker.sessionContext.transactionHandlerFactory.Create()
	if err != nil {
		return []reflect.Value{reflect.ValueOf(err)}
	}
	defer transactionHandler.Close()
	requestContext.session = transactionHandler.Session()
	if err := transactionHandler.Begin(); err != nil {
		// Todo Log
		return []reflect.Value{reflect.ValueOf(err)}
	}
	out := broker.caller(in)
	lastReturnValue := out[len(out)-1]
	switch lastReturnValue.Kind() {
	case reflect.Invalid:
		{
			if err := transactionHandler.Commit(); err != nil {
				// Todo Log
				return []reflect.Value{reflect.ValueOf(err)}
			}
		}
	case reflect.Interface:
		{
			if lastReturnValue.Type() == errorType && lastReturnValue.IsNil() {
				if err := transactionHandler.Commit(); err != nil {
					// Todo Log
					return []reflect.Value{reflect.ValueOf(err)}
				}
			}
		}
	}
	return out
}
