// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved.

package container

import (
	"fmt"
	"reflect"
	"testing"
)

func TestDefaultInformationManager_New(t *testing.T) {

	defaultInformationManager := NewDefaultInformationManager()
	if defaultInformationManager == nil {
		t.Fatalf("创建失败!")
	}
	if len(defaultInformationManager.informationMapping) != 0 {
		t.Fatalf("组件列表数量错误!")
	}
}

func TestDefaultInformationManager_Item(t *testing.T) {

	informationManager := NewDefaultInformationManager()
	elementInformation := NewElementInformation(FactoryOfTestElement)
	informationManager.informationMapping[testElementType] = elementInformation
	if informationManager.Item(testElementType) == nil {
		t.Fatalf("意外未找到了组件信息!")
	}
	if informationManager.Item(testElementType) != elementInformation {
		t.Fatalf("获取组件信息错误!")
	}
	if informationManager.Item(testServiceType) != nil {
		t.Fatalf("意外找到了组件信息!")
	}
}

func TestDefaultInformationManager_Item_NullError(t *testing.T) {

	informationManager := NewDefaultInformationManager()
	information := informationManager.Item(nil)
	if information != nil {
		t.Fatal("意外的查到了数据!")
	}
}

func TestDefaultInformationManager_Items(t *testing.T) {

	informationManager := NewDefaultInformationManager()
	elementInformation := NewElementInformation(FactoryOfTestElement)
	informationManager.informationMapping[testElementType] = elementInformation
	if len(informationManager.Items()) != 1 {
		t.Fatalf("组件列表数量错误!")
	}
	if informationManager.Items()[0] != elementInformation {
		t.Fatalf("获取组件信息列表错误!")
	}
}

func TestDefaultInformationManager_RegisterElement(t *testing.T) {

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(FactoryOfTestElement, false)
	information, ok := informationManager.informationMapping[testElementType]
	if !ok {
		t.Fatalf("未找到组件!")
	}
	if information == nil {
		t.Fatalf("没找到信息")
	}
	elementInformation, ok := information.(*ElementInformation)
	if !ok {
		t.Fatalf("Information类型不正确!")
	}
	if testElementType != elementInformation.Interface() {
		t.Fatalf("接口类型不正确!")
	}
}

func TestDefaultInformationManager_RegisterGlobalElement(t *testing.T) {
	defer func() {
		if err := recover(); err != "目前不支持全局组件!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(FactoryOfTestElement, true)
	t.Fatalf("意外的没有错误!")
}

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

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(nil, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterElement_FactoryTypeError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂必须是func!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(reflect.TypeOf(FactoryOfTestElement()), false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterElement_ParameterCountError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂不能有参数!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(FactoryOfElementTestInterfaceWithContent, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterElement_NoReturnValueError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂必值需有返回值!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(FactoryWithoutResult, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterElement_TooManyResultsError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂只能有一个返回值!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(FactoryWithTooManyResults, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterElement_ReturnValueTypeError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂的返回值必需是interface!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(FactoryOfTestElementImplement, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterElement_Repeat(t *testing.T) {
	defer func() {
		if err := recover(); err != fmt.Sprintf("组件%s接口已经注册!", testElementType.Name()) {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	informationManager.RegisterElement(FactoryOfTestElement, false)
	informationManager.RegisterElement(FactoryOfTestElement, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterService(t *testing.T) {

	informationManager := NewDefaultInformationManager()
	serviceInformation := informationManager.RegisterService(FactoryOfTestService, false)
	if serviceInformation == nil {
		t.Fatalf("注册失败!")
	}
	information, ok := informationManager.informationMapping[testServiceType]
	if !ok {
		t.Fatalf("未找到组件!")
	}
	if information == nil {
		t.Fatalf("没找到信息")
	}
	serviceInformation, ok = information.(*ServiceInformation)
	if !ok {
		t.Fatalf("Information类型不正确!")
	}
	if testServiceType != serviceInformation.Interface() {
		t.Fatalf("接口类型不正确!")
	}
}

func TestDefaultInformationManager_RegisterGlobalService(t *testing.T) {
	defer func() {
		if err := recover(); err != "目前不支持全局组件!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	_ = informationManager.RegisterService(FactoryOfTestService, true)
	t.Fatalf("意外的没有错误!")
}

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

	informationManager := NewDefaultInformationManager()
	_ = informationManager.RegisterService(nil, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterService_FactoryTypeError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂必须是func!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	_ = informationManager.RegisterService(reflect.TypeOf(FactoryOfTestElement()), false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterService_ParameterCountError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂不能有参数!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	_ = informationManager.RegisterService(FactoryOfServiceTestInterfaceWithContent, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterService_NoReturnValueError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂必值需有返回值!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	_ = informationManager.RegisterService(FactoryWithoutResult, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterService_TooManyResultsError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂只能有一个返回值!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	_ = informationManager.RegisterService(FactoryWithTooManyResults, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterService_ReturnValueTypeError(t *testing.T) {
	defer func() {
		if err := recover(); err != "工厂的返回值必需是interface!" {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	_ = informationManager.RegisterService(FactoryOfTestElementImplement, false)
	t.Fatalf("意外的没有错误!")
}

func TestDefaultInformationManager_RegisterService_Repeat(t *testing.T) {
	defer func() {
		if err := recover(); err != fmt.Sprintf("组件%s接口已经注册!", testServiceType.Name()) {
			t.Fatalf("意外错误:%s", err)
		}
	}()

	informationManager := NewDefaultInformationManager()
	_ = informationManager.RegisterService(FactoryOfTestService, false)
	_ = informationManager.RegisterService(FactoryOfTestService, false)
	t.Fatalf("意外的没有错误!")
}
