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

import cc.smtweb.framework.core.cache.CacheManager;
import cc.smtweb.framework.core.cache.ISwCache;
import cc.smtweb.framework.core.cache.redis.RedisManager;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.mvc.SchedulerManager;
import cc.smtweb.framework.core.mvc.controller.access.IMethodAccess;
import cc.smtweb.framework.core.mvc.controller.access.MethodAccess;
import cc.smtweb.framework.core.mvc.controller.scan.BeanManager;
import cc.smtweb.framework.core.mvc.realm.service.PermChecker;
import cc.smtweb.framework.core.mvc.scheduler.SchedulerTaskManager;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 服务方法调用管理，通过url进行API调用
 *
 * @author xkliu
 */
@Slf4j
public class MethodAccessManager {
    private Map<String, IMethodAccess> controllers;
    private IBeanContext beanContext;
    private SchedulerTaskManager schedulerTaskManager;
    private MethodAccess[] destroyMethods;

    @Getter
    private CacheManager cacheManager;

    public MethodAccessManager(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    // 执行控制器方法
    Object invoke(String url, Map<String, Object> params, String body, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 调用普通方法
//    String url = module + "/" + service + "/" + method;

        IMethodAccess methodAccess = controllers.get(url);

        if (methodAccess != null) {
            return methodAccess.invoke(beanContext, params, body, request);
        }

        // TODO 调用默认方法
//    url = module + "/" + service + "/";
//
//    methodAccess = controllers.get(url);
//
//    if (methodAccess != null) {
//      permInterceptor.preHandle(request, methodAccess.getPerm());
//
//      request.setAttribute(PathParamEditor.ATTR_KEY, method);
//      return methodAccess.invoke(beanContext, params, body, request, response);
//    }

        return R.error(404, "not find api:" + url);
    }

    public void init(BeanManager beanManager, ISwCache<Long, PermChecker> cache) {
        this.beanContext = beanManager.getBeanContext();
        this.controllers = beanManager.getControllers();
        this.destroyMethods = beanManager.loadDestroyMethods();

        // 启动定时任务
        this.schedulerTaskManager = SchedulerTaskManager.build(beanContext, beanManager.getTasks());

        if (this.schedulerTaskManager != null) {
            // 设置用于外部服务调用
            SchedulerManager schedulerManager = this.beanContext.getBean(SchedulerManager.class);
            if (schedulerManager != null) {
                schedulerManager.install(this.schedulerTaskManager);
            } else {
                log.error("not find spring bean schedulerManager");
            }
        }
    }

    void showdown() {
        // 强行关闭定时任务
        if (this.schedulerTaskManager != null) {
            this.schedulerTaskManager.shutdown();
        }

        if (destroyMethods != null) {
            for (MethodAccess methodAccess : destroyMethods) {
                try {
                    methodAccess.invoke(beanContext);
                } catch (Exception e) {
                    log.error(methodAccess.fullName(), e);
                }
            }
        }
    }
}
