package container

import (
	"LAPP_ACURA_MOM_BACKEND/global"
	"errors"
	"fmt"
	"reflect"
	"testing"
)

func TestServiceMethodInformation_New(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	serviceMethodInformation := NewServiceMethodInformation(&method)
	if serviceMethodInformation == nil {
		t.Fatalf("创建失败!")
	}
	if serviceMethodInformation.methodName != methodName {
		t.Fatalf("方法名设置错误!")
	}
	if serviceMethodInformation.methodType != method.Type {
		t.Fatalf("方法类型设置错误!")
	}
	if serviceMethodInformation.routerBuilder != nil {
		t.Fatalf("路由创建器设置错误!")
	}
	if serviceMethodInformation.callerBrokerBuilders == nil {
		t.Fatalf("调用器代理创建器列表设置错误!")
	}
	if len(serviceMethodInformation.callerBrokerBuilders) != 1 {
		t.Fatalf("调用器代理创建器列表数量错误!")
	}
}

func TestServiceMethodInformation_New_NullError(t *testing.T) {
	defer func() {
		if err := recover(); err != "方法类型不能为空!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	_ = NewServiceMethodInformation(nil)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_New_EmptyMethodName(t *testing.T) {
	defer func() {
		if err := recover(); err != "方法名不能为空!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	method := reflect.Method{Name: "", Type: nil}
	_ = NewServiceMethodInformation(&method)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_New_ReturnValuesCountError(t *testing.T) {

	methodName := "String2"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	defer func() {
		if err := recover(); err != fmt.Sprintf("返回值数量错误! 返回值数量: %d", method.Type.NumOut()) {
			t.Fatalf("意外错误:%s", err)
		}
	}()
	_ = NewServiceMethodInformation(&method)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_New_ReturnValueTypeError(t *testing.T) {

	methodName := "NoError"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	defer func() {
		if err := recover(); err != fmt.Sprintf("最后一个返回值类型错误! 类型:%s", method.Type.Out(method.Type.NumOut()-1)) {
			t.Fatalf("意外错误:%s", err)
		}
	}()
	_ = NewServiceMethodInformation(&method)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_MethodName(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	information.methodName = methodName
	if information.MethodName() != methodName {
		t.Fatalf("方法名获取错误!")
	}
}

func TestServiceMethodInformation_MethodType(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	information.methodType = method.Type
	if information.MethodType() != method.Type {
		t.Fatalf("方法类型获取错误!")
	}
}

func TestServiceMethodInformation_RouterBuilder(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	testError := errors.New("TestError")
	var routerBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error) {
		return "", "", "", testError
	}
	information.routerBuilder = routerBuilder
	storedRouterBuilder := information.RouterBuilder()
	if storedRouterBuilder == nil {
		t.Fatalf("获取到的路由创建器不应为空!")
	}
	_, _, _, testError2 := storedRouterBuilder(nil, "", nil)
	if testError2 != testError {
		t.Fatalf("路由创建器获取错误!")
	}
}

func TestServiceMethodInformation_AppendBrokerBuilder(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	if information == nil {
		t.Fatalf("没找到信息")
	}
	var callerBrokerBuilder CallerBrokerBuilder = new(TestCallerBrokerBuilderImplement)
	information.AppendBrokerBuilder(callerBrokerBuilder)
	expectedLength := 2
	if len(information.callerBrokerBuilders) != expectedLength {
		t.Fatalf("调用器代理创建器数量错误!预期:%d,实际:%d.", expectedLength, len(information.callerBrokerBuilders))
	}
	if information.callerBrokerBuilders[1] != callerBrokerBuilder {
		t.Fatalf("调用器代理创建器设置错误!")
	}
}

func TestServiceMethodInformation_AppendBrokerBuilder_NullError(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	defer func() {
		if err := recover(); err != fmt.Sprintf("调用器代理创建器不能设置为空!") {
			t.Fatalf("意外错误:%s", err)
		}
	}()
	information.AppendBrokerBuilder(nil)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_AppendBrokerBuilder_CheckError(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	testError := errors.New("TestError")
	var callerBrokerBuilder CallerBrokerBuilder = &TestCallerBrokerBuilderImplementWithError{checkingError: testError}
	defer func() {
		if err := recover(); err != testError.Error() {
			t.Fatalf("意外错误:%s", err)
		}
	}()
	information.AppendBrokerBuilder(callerBrokerBuilder)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_SetRouterBuilder(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	testError := errors.New("TestError")
	var routerBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error) {
		return "", "", "", testError
	}
	information.SetRouterBuilder(routerBuilder)
	storedRouterBuilder := information.routerBuilder
	if storedRouterBuilder == nil {
		t.Fatalf("获取到的路由创建器不应为空!")
	}
	_, _, _, testError2 := storedRouterBuilder(nil, "", nil)
	if testError2 != testError {
		t.Fatalf("路由创建器获取错误!")
	}
}

func TestServiceMethodInformation_SetRouterBuilder_NullError(t *testing.T) {
	defer func() {
		if err := recover(); err != "路由创建器不能设置为空!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	information.SetRouterBuilder(nil)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_SetRouterBuilder_RepeatedError(t *testing.T) {
	defer func() {
		if err := recover(); err != "已经设置路由创建器!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	testError := errors.New("TestError")
	var routerBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error) {
		return "", "", "", testError
	}
	information.SetRouterBuilder(routerBuilder)
	information.SetRouterBuilder(routerBuilder)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_SetBuilders(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	if information == nil {
		t.Fatalf("没找到信息")
	}
	if information.methodName != methodName {
		t.Fatalf("方法名设置错误!")
	}
	if information.MethodName() != methodName {
		t.Fatalf("方法名获取错误!")
	}
	if information.methodType != method.Type {
		t.Fatalf("方法类型设置错误!")
	}
	if information.MethodType() != method.Type {
		t.Fatalf("方法类型获取错误!")
	}

	testError := errors.New("TestError")

	var routerBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error) {
		return "", "", "", testError
	}

	var callerBrokerBuilder CallerBrokerBuilder = new(TestCallerBrokerBuilderImplement)

	builders := BuilderSet{routerBuilder, []CallerBrokerBuilder{callerBrokerBuilder}}

	information.SetBuilders(builders)
	if information.routerBuilder == nil {
		t.Fatalf("路由创建器不应为空!")
	}
	_, _, _, testError1 := information.routerBuilder(nil, "", nil)
	if testError1 != testError {
		t.Fatalf("路由创建器设置错误!")
	}
	expectedLength := 2
	if len(information.callerBrokerBuilders) != expectedLength {
		t.Fatalf("调用器代理创建器数量错误!预期:%d,实际:%d.", expectedLength, len(information.callerBrokerBuilders))
	}
	if information.callerBrokerBuilders[1] != callerBrokerBuilder {
		t.Fatalf("调用器代理创建器设置错误!")
	}
}

func TestServiceMethodInformation_SetBuilders_NullBrokerBuilderError(t *testing.T) {
	defer func() {
		if err := recover(); err != "调用器代理创建器不能设置为空!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	testError := errors.New("TestError")
	var routerBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error) {
		return "", "", "", testError
	}
	builders := BuilderSet{routerBuilder, []CallerBrokerBuilder{nil}}
	information.SetBuilders(builders)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_SetBuilders_MethodCheckError(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	testError := errors.New("TestError")
	var routerBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error) {
		return "", "", "", testError
	}
	var callerBrokerBuilder CallerBrokerBuilder = &TestCallerBrokerBuilderImplementWithError{checkingError: testError}
	builders := BuilderSet{routerBuilder, []CallerBrokerBuilder{callerBrokerBuilder}}
	defer func() {
		if err := recover(); err != testError.Error() {
			t.Fatalf("意外错误:%s", err)
		}
	}()
	information.SetBuilders(builders)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_SetBuilders_NullRouterBuilderError(t *testing.T) {
	defer func() {
		if err := recover(); err != "路由创建器不能设置为空!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	builders := BuilderSet{nil, nil}
	information.SetBuilders(builders)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_SetBuilders_RepeatedRouterBuilderError(t *testing.T) {
	defer func() {
		if err := recover(); err != "已经设置路由创建器!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	testError := errors.New("TestError")
	var routerBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error) {
		return "", "", "", testError
	}
	builders := BuilderSet{routerBuilder, nil}
	information.SetBuilders(builders)
	information.SetBuilders(builders)
	t.Fatalf("意外的没有错误!")
}

func TestServiceMethodInformation_BuildHandler(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	userId := "userId"
	user := &global.User{UserId: userId}
	sessionContext, err := NewSessionContext(user, transactionHandlerFactoryMock)
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	handler, err := information.BuildHandler(sessionContext, serviceInstance)
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	if handler == nil {
		t.Fatalf("创建句柄错误!")
	}
}

func TestServiceMethodInformation_BuildHandler_NullSession(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	_, err := information.BuildHandler(nil, serviceInstance)
	if err == nil {
		t.Fatalf("会话不能为空!")
	}
	if err.Error() != fmt.Sprintf("会话上下文不能为空!") {
		t.Fatalf("意外错误:%s", err.Error())
	}
}

func TestServiceMethodInformation_BuildHandler_EmptyMethodNameError(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	userId := "userId"
	user := &global.User{UserId: userId}
	sessionContext, err := NewSessionContext(user, transactionHandlerFactoryMock)
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	information.methodName = ""
	_, err = information.BuildHandler(sessionContext, serviceInstance)
	if err == nil {
		t.Fatalf("意外的没有错误!")
	}
	if err.Error() != fmt.Sprintf("方法名不能为空!") {
		t.Fatalf("意外错误:%s", err.Error())
	}
}

func TestServiceMethodInformation_BuildHandler_MissingMethodError(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	userId := "userId"
	user := &global.User{UserId: userId}
	sessionContext, err := NewSessionContext(user, transactionHandlerFactoryMock)
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	information.methodName = ""
	information.methodName = "NoMethod"
	_, err = information.BuildHandler(sessionContext, serviceInstance)
	if err == nil {
		t.Fatalf("意外的没有错误!")
	}
	if err.Error() != fmt.Sprintf("未找到方法!") {
		t.Fatalf("意外错误:%s", err.Error())
	}
}

func TestServiceMethodInformation_BuildHandler_BrokerBuildError(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	testError := errors.New("TestError")
	var callerBrokerBuilder CallerBrokerBuilder = &TestCallerBrokerBuilderImplementWithError{buildingError: testError}
	information.AppendBrokerBuilder(callerBrokerBuilder)
	userId := "userId"
	user := &global.User{UserId: userId}
	sessionContext, err := NewSessionContext(user, transactionHandlerFactoryMock)
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	_, err = information.BuildHandler(sessionContext, serviceInstance)
	if err == nil {
		t.Fatalf("意外的没有错误!")
	}
	if err != testError {
		t.Fatalf("意外错误:%s", err.Error())
	}
}

func TestServiceMethodInformation_BuildHandler_NullCallerError(t *testing.T) {

	methodName := "String"
	method, ok := testServiceType.MethodByName(methodName)
	if !ok {
		t.Fatalf("意外的没找到方法!")
	}
	information := NewServiceMethodInformation(&method)
	var callerBrokerBuilder CallerBrokerBuilder = new(TestCallerBrokerBuilderImplementWithError)
	information.AppendBrokerBuilder(callerBrokerBuilder)
	userId := "userId"
	user := &global.User{UserId: userId}
	sessionContext, err := NewSessionContext(user, transactionHandlerFactoryMock)
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	_, err = information.BuildHandler(sessionContext, serviceInstance)
	if err == nil {
		t.Fatalf("意外的没有错误!")
	}
	if err.Error() != fmt.Sprintf("第2个调用器不能为空!") {
		t.Fatalf("意外错误:%s", err.Error())
	}
}
