package cc.smtweb.framework.core.mvc.controller.access;

import cc.smtweb.framework.core.mvc.controller.IBeanContext;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * 控制器访问类
 */
@Slf4j
public class ControllerAccess implements IBeanAccess {
    private final Class<?> clazz;
    private final List<FieldAccess> fieldList;
    @Getter
    private final boolean singleton;
    @Getter
    private Object singletonInstance;

    public ControllerAccess(Class<?> clazz, List<FieldAccess> fieldList, boolean singleton) {
        this.clazz = clazz;
        this.fieldList = fieldList;
        this.singleton = singleton;
    }

    public String getFullName() {
        return clazz.getName();
    }

    public Object getOrNewInstance(IBeanContext context, Map<String, Object> params) throws IllegalAccessException, InstantiationException {
        if (singletonInstance != null) {
            return singletonInstance;
        } else {
            Object result = clazz.newInstance();

            writeBeanFields(result, context, params);

            return result;
        }
    }

    private void writeBeanFields(Object bean, IBeanContext context, Map<String, Object> params) {
        for (FieldAccess fieldAccess : fieldList) {
            boolean ret = fieldAccess.writeValue(bean, context, params);
            if (!ret) {
                log.error("write bean " + fieldAccess.getFullName(bean)
                        + " failure.");
            }
        }
    }

    public Object initSingletonFields(IBeanContext context, Map<String, Object> params) {
        if (singletonInstance != null) {
            writeBeanFields(singletonInstance, context, params);
        }

        return singletonInstance;
    }

    public Class<?> getBeanType() {
        return clazz;
    }

    public void newSingletonInstance() throws IllegalAccessException, InstantiationException {
        if (isSingleton()) {
            this.singletonInstance = clazz.newInstance();
        }
    }
}
