package com.yunfeiyun.agmp.fms.controller;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yunfeiyun.agmp.common.constant.ErrorCode;
import com.yunfeiyun.agmp.common.core.domain.model.IBaseMenu;
import com.yunfeiyun.agmp.common.core.domain.model.IBaseOperLog;
import com.yunfeiyun.agmp.common.exception.BizException;
import com.yunfeiyun.agmp.common.web.system.mapper.SysMenuMapper;
import com.yunfeiyun.agmp.common.web.system.mapper.SysOperLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

    @Resource
    private SysMenuMapper service;
    @Resource
    private SysOperLogMapper sysOperLogMapper;
    /**
     * 查询系统预警列表
     */
    @PreAuthorize("@ss.hasPermi('test:list')")
    @GetMapping("/list")
    public void list(String apiPostJsonUrl) throws ClassNotFoundException {
        List<IBaseMenu> list =  service.selectMenuList(null);
        List<IBaseOperLog> operLogs = sysOperLogMapper.selectOperLogList(null);
        List<String> methodName = operLogs.stream().map(IBaseOperLog::getOperMethod).collect(Collectors.toList());
        Map<String,IBaseMenu> menuMap = new HashMap<>();
        for(IBaseMenu baseMenu : list){
            menuMap.put("@ss.hasPermi('" + baseMenu.getMenuPerms() +"')",baseMenu);
        }
        String packageName = "com.yunfeiyun.fms.web.controller.system";  // 替换为你要扫描的包名
        String packagePath = packageName.replace('.', '/');
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        URL packageURL = classLoader.getResource(packagePath);
        File packageDir = new File(packageURL.getPath());
        File[] classFiles = packageDir.listFiles();
        List<String> fmsNoExistMenu = new ArrayList<>();
        List<String> wmsNoExistMenu = new ArrayList<>();
        List<String> pathJson = readJson(apiPostJsonUrl);
        if (classFiles != null) {
            for (File classFile : classFiles) {
                String className = classFile.getName().replace(".class", "");
                String fullClassName = packageName + "." + className;
                Class<?> targetClass = Class.forName(fullClassName);
                RequestMapping classMapping = targetClass.getAnnotation(RequestMapping.class);
                String controllerPath = classMapping.value()[0];
                Method[] methods = targetClass.getDeclaredMethods();
                for (Method method : methods) {
                    if(methodName.contains(fullClassName+"."+method.getName()+"()")){
                        if (method.isAnnotationPresent(PreAuthorize.class)) {
                            PreAuthorize annotation = method.getAnnotation(PreAuthorize.class);
                            RequestMapping ReqMapping = method.getAnnotation(RequestMapping.class);
                            GetMapping getMapping = method.getAnnotation(GetMapping.class);
                            PostMapping postMapping = method.getAnnotation(PostMapping.class);
                            DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
                            PutMapping putMapping = method.getAnnotation(PutMapping.class);
                            String path = "";
                            if(ReqMapping != null &&ReqMapping.value().length>0 ){
                                path =  ReqMapping.value()[0];
                            }else if(getMapping !=null&&getMapping.value().length>0 ) {
                                path =  getMapping.value()[0];
                            }else if(postMapping !=null &&postMapping.value().length>0) {
                                path =postMapping.value()[0];
                            }else if(deleteMapping !=null &&deleteMapping.value().length>0) {
                                path =  deleteMapping.value()[0];
                            }else if(putMapping !=null &&putMapping.value().length>0) {
                                path =  putMapping.value()[0];
                            }
                            String methodPath  = controllerPath + path;
                            String parameterValue = annotation.value();
                            if(pathJson.contains(methodPath) && (menuMap.get(parameterValue)== null )){
                                    log.info(methodPath + ","+parameterValue);

                            }

                        }
                    }

                }
            }
        }

    }



    private static List<String> readJson(String apiPostJsonUrl){
        try (BufferedReader reader = new BufferedReader(new FileReader(apiPostJsonUrl))) {
            StringBuilder jsonContent = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                jsonContent.append(line);
            }
            List<String> pathArray = new ArrayList<>();
            processJSONObject(JSONObject.parse(jsonContent.toString()),pathArray);
            // 处理读取到的 JSON 内容
           return pathArray;
        } catch (IOException e) {
           throw new BizException(ErrorCode.TSS_TRACE_CODE_TPL_NOT_EXIST);
        }
    }

    public static void processJSONObject(JSONObject jsonObject,List<String> returnList) {
        for (String key : jsonObject.keySet()) {
            Object value = jsonObject.get(key);
            if (value instanceof JSONObject) {
                processJSONObject((JSONObject) value,returnList);
            } else if (value instanceof JSONArray) {
                processJSONArray((JSONArray) value,returnList);
            } else {
                if(key.equals("mock_url")){
                    returnList.add(value.toString());
                }
            }
        }
    }

    public static void processJSONArray(JSONArray jsonArray,List<String> returnList) {
        for (int i = 0; i < jsonArray.size(); i++) {
            Object item = jsonArray.get(i);
            if (item instanceof JSONObject) {
                processJSONObject((JSONObject) item,returnList);
            } else if (item instanceof JSONArray) {
                processJSONArray((JSONArray) item,returnList);
            }
        }
    }

}
