package com.kingdee.eas.custom.sso;

import com.alibaba.fastjson.JSON;
import com.kingdee.eas.utils.ExpiringMapCache;
import com.kingdee.shr.base.syssetting.exception.SHRWebException;
import com.kingdee.util.StringUtils;
import org.apache.log4j.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Random;

/**
 * @Description OA移动端单点移动bos
 * @Date 2024/10/30 11:22
 * @Created by Heyuan
 */
public class OAToMBos extends HttpServlet {
    private static Logger logger = Logger.getLogger(OAToMBos.class);
    private static ExpiringMapCache<String, String> redirectUrlCache = new ExpiringMapCache<>();
    private Properties prop = new Properties();
    private String propPath = System.getProperty("EAS_HOME") + "/server/properties/scy/OAToMBosConfig.properties";
    private final String MBOSAPPROVECENTERURL = "https://mbos.kdeascloud.com/mbos/page/loadPage?appid=10036&eid={0}&path=lczs2&name=lczshome.navui";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        logger.error("OAToMBos -> doGet");
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        logger.error("OAToMBos -> doPost");
        BufferedReader streamReader = null;
        String resultStr = null;
        prop.load(new FileInputStream(propPath));
        logger.error("OAToMBos  requestUrl" + req.getRequestURL().toString());
        try {
            String ticket = req.getParameter("ticket");
            String token = req.getParameter("token");
            logger.error("接收到的请求参数是：ticket " + ticket);
            if (!StringUtils.isEmpty(ticket)) {
                //重定向到Mbos
                redirectMbos(req, resp, ticket);
            } else if (!StringUtils.isEmpty(token)) {
                //获取用户信息(mbos回调)
                getTokenUrl(req, resp, token);
            } else {
                //认证
                authorize(req, resp);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Map result = new HashMap();
            result.put("msgType", "0");
            result.put("reason", e.getMessage());
            resultStr = JSON.toJSONString(result);
            resp.setStatus(500);
            PrintWriter writer = resp.getWriter();
            resp.setContentType("application/json");
            writer.write(resultStr);
            writer.close();
        } finally {
            try {
                if (streamReader != null) {
                    streamReader.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 重定向到mbos
     *
     * @param req
     * @param resp
     * @param ticket
     * @throws IOException
     */
    private void redirectMbos(HttpServletRequest req,
                              HttpServletResponse resp,
                              String ticket) throws IOException {
        if (StringUtils.isEmpty(ticket)) {
            throw new RuntimeException("ticket不能为空!");
        }
        String getAccessTokenPath = prop.getProperty("getAccessTokenPath");
        if (StringUtils.isEmpty(getAccessTokenPath)) {
            throw new RuntimeException("getAccessTokenPath不能为空! 请检查配置文件: " + propPath);
        }
        String serverName = prop.getProperty("serverName");
        if (StringUtils.isEmpty(serverName)) {
            throw new RuntimeException("serverName不能为空! 请检查配置文件: " + propPath);
        }
        String client_secret = prop.getProperty("client_secret");
        if (StringUtils.isEmpty(client_secret)) {
            throw new RuntimeException("client_secret不能为空! 请检查配置文件: " + propPath);
        }
        String client_id = prop.getProperty("client_id");
        if (StringUtils.isEmpty(client_id)) {
            throw new RuntimeException("client_id不能为空! 请检查配置文件: " + propPath);
        }
        String redirect_uri2 = prop.getProperty("redirect_uri2");
        if (StringUtils.isEmpty(redirect_uri2)) {
            throw new RuntimeException("redirect_uri2不能为空! 请检查配置文件: " + propPath);
        }
        String getLoginIdPath = prop.getProperty("getLoginIdPath");
        if (StringUtils.isEmpty(getLoginIdPath)) {
            throw new RuntimeException("getLoginIdPath不能为空! 请检查配置文件: " + propPath);
        }
        String redirectUrlKey = req.getParameter("redirect");
        logger.error("callBack redirectUrl" + redirectUrlKey);
        Map params = new HashMap();
        params.put("client_id", client_id);
        params.put("client_secret", client_secret);
        params.put("grant_type", "authorization_code");
        params.put("code", ticket);
        params.put("redirect_uri", URLEncoder.encode(redirect_uri2, "UTF-8"));
        try {
            String redirectUrl = null;
            String token = SsoUtil.getAccessToken(getAccessTokenPath, params);
            logger.error(token);
            if (StringUtils.isEmpty(redirectUrlKey)) {
                String eid = prop.getProperty("eid");
                if (org.apache.commons.lang3.StringUtils.isEmpty(eid)) {
                    throw new RuntimeException("eid不能为空! 请检查配置文件: " + propPath);
                }
                redirectUrl = MessageFormat.format(MBOSAPPROVECENTERURL, eid);
            } else {
                redirectUrl = redirectUrlCache.get(redirectUrlKey);
            }
            Map toMbosparams = new HashMap();
            toMbosparams.put("token", token);
            //todo
            //校验流程生效状态
            //redirectUrl = SsoUtil.checkFlowEffectiveStateForMbos(redirectUrl, serverName, getLoginIdPath, token);
            redirectUrl = SsoUtil.checkBillExistForMbos(redirectUrl, serverName, getLoginIdPath, token);
            String urlString = SsoUtil.appendUrl(redirectUrl, toMbosparams);
            resp.sendRedirect(urlString);
            logger.error("redirectMbos url" + urlString);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 认证
     * 拼接OA认证接口地址，转发
     *
     * @param resp
     * @throws Exception
     */
    public void authorize(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        String authorizePath = prop.getProperty("authorizePath");
        if (StringUtils.isEmpty(authorizePath)) {
            throw new RuntimeException("authorizePath不能为空! 请检查配置文件: " + propPath);
        }
        String response_type = prop.getProperty("response_type");
        if (StringUtils.isEmpty(response_type)) {
            throw new RuntimeException("response_type不能为空! 请检查配置文件: " + propPath);
        }
        String client_id = prop.getProperty("client_id");
        if (StringUtils.isEmpty(client_id)) {
            throw new RuntimeException("client_id不能为空! 请检查配置文件: " + propPath);
        }
        String redirect_uri1 = prop.getProperty("redirect_uri1");
        if (StringUtils.isEmpty(redirect_uri1)) {
            throw new RuntimeException("redirect_uri1不能为空! 请检查配置文件: " + propPath);
        }
        String redirectUrl = req.getParameter("redirect");
        if (StringUtils.isEmpty(redirectUrl)) {
            redirectUrl = MBOSAPPROVECENTERURL;
        }
        Random random = new Random();
        String key = System.currentTimeMillis() + String.valueOf(random.nextInt(99999));
        redirectUrlCache.put(key, redirectUrl, 300000);
        logger.error("callBack redirectUrl" + redirectUrl);
        redirect_uri1 += "?redirect=" + key;
        Map params = new HashMap();
        params.put("client_id", client_id);
        params.put("response_type", response_type);
        params.put("redirect_uri", URLEncoder.encode(redirect_uri1, "UTF-8"));
        String urlString = SsoUtil.appendUrl(authorizePath, params);
        resp.sendRedirect(urlString);
        logger.error("authorize url" + urlString);
    }

    /**
     * 获取用户信息
     * 用户信息
     *
     * @param req
     * @param resp
     * @param token
     * @throws SHRWebException
     * @throws UnsupportedEncodingException
     */
    public void getTokenUrl(HttpServletRequest req,
                            HttpServletResponse resp, String token) throws
            SHRWebException, IOException {
        logger.error("getTokenUrl方法入参");
        if (StringUtils.isEmpty(token)) {
            throw new RuntimeException("token不能为空!");
        }
        String getLoginIdPath = prop.getProperty("getLoginIdPath");
        if (StringUtils.isEmpty(getLoginIdPath)) {
            throw new RuntimeException("getLoginIdPath不能为空! 请检查配置文件: " + propPath);
        }
        Map result = new HashMap();
        try {
            //从人员对象，获取纷享用户userId
            String loginId = SsoUtil.loginId2userId(getLoginIdPath, token);
            result.put("status", "0");
            result.put("message", loginId);
            resp.setStatus(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.put("status", "1");
            result.put("message", e.getMessage());
            resp.setStatus(500);
        }
        PrintWriter writer = resp.getWriter();
        resp.setContentType("application/json");
        writer.write(JSON.toJSONString(result));
        writer.close();
    }
}
