package com.malk.apigw.controller;

import com.alibaba.fastjson.JSONObject;
import com.malk.apigw.action.ActionHandler;
import com.malk.apigw.action.ActionRegistry;
import com.malk.apigw.caller.CallerProfile;
import com.malk.apigw.caller.CallerRegistryProperties;
import com.malk.apigw.config.CallerAuthInterceptor;
import com.malk.server.common.McR;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * BaaS 网关入口 {@code POST /{vendor}/{action}}
 */
@RestController
@RequestMapping("/")
public class GatewayController {

    private static final Logger log = LoggerFactory.getLogger("point");

    @Autowired
    private ActionRegistry actionRegistry;

    @Autowired
    private CallerRegistryProperties props;

    @PostMapping("/{vendor}/{action}")
    public McR dispatch(@PathVariable String vendor,
                        @PathVariable String action,
                        @RequestBody(required = false) JSONObject body,
                        HttpServletRequest request) {
        String key = vendor + "." + action;
        if (body == null) body = new JSONObject();

        // 1. 代码层白名单
        ActionHandler handler = actionRegistry.get(key);
        if (handler == null) {
            return McR.error("ACTION_NOT_FOUND", "action 未注册: " + key);
        }

        // 2. yml 全局启用白名单
        List<String> enabled = props.getActions().getEnabled();
        if (enabled != null && !enabled.isEmpty() && !enabled.contains(key)) {
            return McR.error("ACTION_FORBIDDEN", "action 未在 com.actions.enabled 启用: " + key);
        }

        // 3. 调用方 allowedActions
        CallerProfile caller = (CallerProfile) request.getAttribute(CallerAuthInterceptor.ATTR_CALLER);
        if (caller == null) {
            return McR.error("AUTH_FAILED", "caller 未认证");
        }
        List<String> allow = caller.getAllowedActions();
        if (allow == null || !allow.contains(key)) {
            return McR.error("ACTION_FORBIDDEN", "caller 无权限: " + key);
        }

        log.info("[Gateway] caller={} action={} ", caller.getCallerId(), key);
        try {
            return handler.handle(caller, body);
        } catch (Exception e) {
            log.error("[Gateway] dispatch failed action={}", key, e);
            return McR.error("VENDOR_ERROR", e.getMessage());
        }
    }
}
