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

package container

import (
	"fmt"
)

// 默认组件信息管理器
// @Implement LAPP_LF_MOM_BACKEND/container/InformationManager
type DefaultInformationManager struct {
	// 组件信息映射: map[组件接口]组件信息
	informationMapping map[Interface]ComponentInformation
}

// 创建默认组件管理器
// 返回值:
// 1.默认组件信息管理器
func NewDefaultInformationManager() *DefaultInformationManager {
	return &DefaultInformationManager{make(map[Interface]ComponentInformation, 100)}
}

// @Reference LAPP_LF_MOM_BACKEND/container/InformationManager.RegisterElement
// 异常:
// 1.工厂不能为空
// 2.工厂必须是func
// 3.工厂不能有参数
// 4.工厂必值需有返回值
// 5.工厂只能有一个返回值
// 6.工厂的返回值必需是interface
// 7.组件接口已经注册
func (manager *DefaultInformationManager) RegisterElement(factory interface{}, isGlobal bool) {

	if isGlobal {
		panic(fmt.Sprintf("目前不支持全局组件!"))
	}
	elementInformation := NewElementInformation(factory)
	elementType := elementInformation.Interface()
	componentName := elementType.Name()
	_, ok := manager.informationMapping[elementType]
	if ok {
		panic(fmt.Sprintf("组件%s接口已经注册!", componentName))
	}
	manager.informationMapping[elementType] = elementInformation
}

// @Reference LAPP_LF_MOM_BACKEND/container/InformationManager.RegisterService
// 异常:
// 1.工厂不能为空
// 2.工厂必须是func
// 3.工厂不能有参数
// 4.工厂必值需有返回值
// 5.工厂只能有一个返回值
// 6.工厂的返回值必需是interface
// 7.组件接口已经注册
func (manager *DefaultInformationManager) RegisterService(factory interface{}, isGlobal bool) *ServiceInformation {

	if isGlobal {
		panic(fmt.Sprintf("目前不支持全局组件!"))
	}
	serviceInformation := NewServiceInformation(factory)
	serviceType := serviceInformation.Interface()
	componentName := serviceType.Name()
	_, ok := manager.informationMapping[serviceType]
	if ok {
		panic(fmt.Sprintf("组件%s接口已经注册!", componentName))
	}
	manager.informationMapping[serviceType] = serviceInformation
	return serviceInformation
}

// @Reference LAPP_LF_MOM_BACKEND/container/InformationManager.Item
func (manager *DefaultInformationManager) Item(interfaceType Interface) ComponentInformation {

	if interfaceType == nil {
		return nil
	}
	item, ok := manager.informationMapping[interfaceType]
	if ok {
		return item
	}
	return nil
}

// @Reference LAPP_LF_MOM_BACKEND/container/InformationManager.Items
func (manager *DefaultInformationManager) Items() []ComponentInformation {

	items := make([]ComponentInformation, len(manager.informationMapping))
	index := 0
	for _, item := range manager.informationMapping {
		items[index] = item
		index++
	}
	return items
}
