package com.palacesun.masking.appuser;

import com.palacesun.engine.gateway.EncryptionGatewayManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.logging.Logger;

public class HttpLoginParamsReceive {
   protected static Logger logger = Logger.getLogger(HttpLoginParamsReceive.class.getName());
   private static HttpServer server;
   private static boolean isServerRunning = false;
   private String sign = "";
   private String focusWaysUserName = "";
   private String signCheck = "";
   public static Map<String, String> singMap = new HashMap();

   public String getSignCheck() {
      return this.signCheck;
   }

   public void setSignCheck(String signCheck) {
      this.signCheck = signCheck;
   }

   public String getFocusWaysUserName() {
      return this.focusWaysUserName;
   }

   public void setFocusWaysUserName(String focusWaysUserName) {
      this.focusWaysUserName = focusWaysUserName;
   }

   public String getSign() {
      return this.sign;
   }

   public void setSign(String sign) {
      this.sign = sign;
   }

   public static void startServer(HttpLoginParamsReceive httpLoginParamsReceive) throws IOException {
      int port = 12321;
      if (!isServerRunning) {
         String receivePort = EncryptionGatewayManager.getParameterValue("receivePort");
         logger.info("Server is running on receivePort " + receivePort);
         if (receivePort != null && !"".equals(receivePort)) {
            port = Integer.parseInt(EncryptionGatewayManager.getParameterValue("receivePort"));
         }

         server = HttpServer.create(new InetSocketAddress(port), 0);
         logger.info("Server is running on server " + server);
         server.createContext(EncryptionGatewayManager.getParameterValue("interface"), new PostHandler(httpLoginParamsReceive));
         logger.info("Server is running on server 1");
         server.setExecutor((Executor)null);
         server.start();
         isServerRunning = true;
         logger.info("Server is running on port " + port);
         System.out.println("Server is running on port " + port);
      }

   }

   public static String convert(InputStream inputStream, String charsetName) throws IOException {
      StringBuilder stringBuilder = new StringBuilder();
      BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charsetName));

      String line;
      while((line = reader.readLine()) != null) {
         stringBuilder.append(line).append("\n");
      }

      return stringBuilder.toString();
   }

   public static String eccAttachVerify(String signData) {
      String check = "1";
      String urlSuffix = "/sign/v1/eccAttachVerify";
      String uKeyUrl = EncryptionGatewayManager.getParameterValue("uKeyUrl") + urlSuffix;
      Map<String, Object> param = new HashMap(2);
      param.put("signedData", signData);
      param.put("needCert", false);

      try {
         String result = doPost(uKeyUrl, JSON.toJSONString(param), getToken());
         JSONObject jsonObject = JSONObject.parseObject(result);
         logger.info("@@插件----get Token jsonObject eccAttachVerify:" + jsonObject);
         if (jsonObject != null && !"".equals(jsonObject)) {
            check = jsonObject.get("code").toString();
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      return check;
   }

   public static String getToken() {
      String token = "";
      String urlSuffix = "/appToken/v1/getAppToken";
      String uKeyUrl = EncryptionGatewayManager.getParameterValue("uKeyUrl") + urlSuffix;
      Map<String, String> param = new HashMap(2);
      param.put("secretKey", EncryptionGatewayManager.getParameterValue("secretKey"));

      try {
         String result = doPost(uKeyUrl, JSON.toJSONString(param), null);
         JSONObject jsonObject = JSONObject.parseObject(result);
         logger.info("@@插件----get Token jsonObject " + jsonObject);
         if (jsonObject != null && !"".equals(jsonObject)) {
            JSONObject tokenData = (JSONObject)jsonObject.get("data");
            logger.info("@@插件----get Token jsonObject token:" + tokenData.get("token"));
            token = tokenData.get("token").toString();
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      return token;
   }

   public static String doPost(String url, String json, String token) {
      CloseableHttpClient httpClient = HttpClients.createDefault();
      HttpPost httpPost = new HttpPost(url);
      String result = null;
      String data = null;

      try {
         httpPost.setHeader("content-type", "application/json");
         httpPost.setHeader("appId", EncryptionGatewayManager.getParameterValue("appId"));
         if (token != null) {
            httpPost.setHeader("gateWayToken", token);
         }

         httpPost.setHeader("timestamp", String.valueOf(System.currentTimeMillis()));
         httpPost.setHeader("nonce", getRandomAlphaNum(10));
         StringEntity se = new StringEntity(json, "utf-8");
         httpPost.setEntity(se);
         HttpResponse response = httpClient.execute(httpPost);
         HttpEntity entity = response.getEntity();
         if (entity != null) {
            result = EntityUtils.toString(entity, "UTF-8");
         }
      } catch (ClientProtocolException e) {
         e.printStackTrace();
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         try {
            httpClient.close();
         } catch (IOException e) {
            e.printStackTrace();
         }

      }

      return result;
   }

   public static String getRandomAlphaNum(int length) {
      String alphaNumeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
      StringBuilder sb = new StringBuilder(length);
      SecureRandom random = new SecureRandom();

      for(int i = 0; i < length; ++i) {
         int randIndex = random.nextInt(alphaNumeric.length());
         char randChar = alphaNumeric.charAt(randIndex);
         sb.append(randChar);
      }

      return sb.toString();
   }

   public static void main(String[] args) throws IOException {
      String strJson = "{\"msg\":\"成功\",\"code\":\"0\",\"data\":{\"token\":\"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJBQkVFODgyRTM1MEU1NTJGNzZmMmRhY2FlYmM3NGZmOTk0YjMyOTg2NWQ1OGRiOTIiLCJuYmYiOjE3MTk5MDA0NDksImV4cCI6MTcxOTkwNDA0OX0.RqebTflVf0H3iah0_pPR8WuWAA-AE8iHR3ub0NHk6_pIzI0_j3-Pv7QkUhsG1mV1Ajv5FXZVQgvw0HWNDpkPJk7agw6Twue7hyoNAvBwk8eMHixJYM49HrOZ9j60fLcip-v35Wyx-V8aXiz5Ood0af43paW7FLyyQ93JK8-nVls\"},\"count\":0}";
      JSONObject jsonObject = JSONObject.parseObject(strJson);
      JSONObject data = (JSONObject)jsonObject.get("data");
      System.out.println(data.get("token").toString());
   }

   static class PostHandler implements HttpHandler {
      private HttpLoginParamsReceive httpLoginParamsReceive;

      public PostHandler(HttpLoginParamsReceive httpLoginParamsReceive) {
         this.httpLoginParamsReceive = httpLoginParamsReceive;
      }

      public void handle(HttpExchange exchange) throws IOException {
         if (exchange.getRequestMethod().equalsIgnoreCase("OPTIONS")) {
            Headers headers = exchange.getResponseHeaders();
            headers.add("Access-Control-Allow-Origin", "*");
            headers.add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
            headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
            exchange.sendResponseHeaders(204, -1L);
         } else {
            Headers headers = exchange.getResponseHeaders();
            headers.add("Access-Control-Allow-Origin", "*");
            headers.add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
            headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
            if ("POST".equalsIgnoreCase(exchange.getRequestMethod())) {
               this.handlePostRequest(exchange);
            } else {
               exchange.sendResponseHeaders(405, -1L);
            }
         }

      }

      private void handlePostRequest(HttpExchange exchange) throws IOException {
         InputStream requestBody = exchange.getRequestBody();
         String body = HttpLoginParamsReceive.convert(requestBody, "UTF-8");
         JSONObject jsonObject = JSONObject.parseObject(body);
         this.httpLoginParamsReceive.sign = (String)jsonObject.get("sign");
         this.httpLoginParamsReceive.focusWaysUserName = (String)jsonObject.get("focusWaysUserName");
         System.out.println("Received POST data: " + body);
         this.httpLoginParamsReceive.signCheck = HttpLoginParamsReceive.eccAttachVerify((String)jsonObject.get("sign"));
         HttpLoginParamsReceive.singMap.put(this.httpLoginParamsReceive.focusWaysUserName, this.httpLoginParamsReceive.signCheck);
         String response = this.httpLoginParamsReceive.signCheck;
         exchange.sendResponseHeaders(200, (long)response.getBytes().length);
         OutputStream os = exchange.getResponseBody();
         os.write(response.getBytes());
         os.close();
      }
   }
}
