package net.northking.cctp.element.core;

import net.northking.cctp.element.core.scanner.LibraryDefinition;
import net.northking.cctp.element.core.support.DefaultBeanFactory;
import net.northking.cctp.element.core.support.DefaultLibraryContext;
import net.northking.cctp.element.log.Logger;
import net.northking.cctp.element.util.Assert;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * Context initializer
 *
 * @author fengxiang.zhang
 * @since 1.0
 */
public class ContextInitializer {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(ContextInitializer.class);
    private DefaultLibraryContext context = new DefaultLibraryContext();
    private Map<String, String> presetParams;
    private LibraryDefinition definition;
    private boolean onlyScan = false;

    public ContextInitializer() {
        logger.debug("初始化库上下文环境开始.");
        DefaultBeanFactory defaultBeanFactory = new DefaultBeanFactory();
        context.setBeanFactory(defaultBeanFactory);
        context.setBeanRegistry(defaultBeanFactory);
    }

    /**
     * Set library definition
     *
     * @param definition
     */
    public ContextInitializer setLibraryDefinition(LibraryDefinition definition) {
        Assert.notNull(definition);
        this.definition = definition;
        return this;
    }

    /**
     * Add library init preset parameters
     *
     * @param preset
     */
    public ContextInitializer setPresetParams(Map<String, String> preset) {
        this.presetParams = preset;
        return this;
    }

    public ContextInitializer setOnlyScan(boolean onlyScan) {
        this.onlyScan = onlyScan;
        return this;
    }

    public ContextInitializer registerBean(Class<?> cls, Object bean) {
        this.context.registerBean(cls, bean);
        return this;
    }

    public ContextInitializer registerBean(Object bean) {
        this.context.registerBean(bean.getClass(), bean);
        return this;
    }

    public ContextInitializer registerLogger(Logger logger) {
        this.context.registerLogger(logger);
        return this;
    }

    /**
     * Create library context instance.
     *
     * @return
     * @throws Exception
     */
    public LibraryContext initialize() throws Exception {
        Assert.notNull(definition);
        context.registerBean(LibraryContext.class, context);
        context.setLibraryDefinition(definition);
        context.initialize(presetParams, onlyScan);
        logger.debug("初始化库上下文环境就绪.");
        return context;
    }
}