import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

public class AudRestApiExecute {
    private static String apAccessToken;

    public static void main(String[] args) {

        try{
            // AUD7 플랫폼 iMgt > 인증 키 관리 > 개인용 Access Token 발급
            // 개인용 고정키로 서버 to 서버 인증 처리
            // 실제 요청할 Rest API
            String restApiUrl = "http://192.168.11.10:8080/matrix7/api/aud-client/server-script";
            apAccessToken = "eyJyZWdEYXRlIjoxNzUxOTYxNjk5MDMyLCJ0eXAiOiJKV1QiLCJpc0R1cExvZ2luIjpmYWxzZSwiYWxnIjoiSFM1MTIifQ.eyJzdWIiOiI5QzlWS3JIMmh2UjdacjB4dk9NaVJBPT0iLCJsb2dpbkZsYWciOiJ0blMyUUtxUVJrT0ZCSWxuamFPZDVBPT0iLCJ1c2VyaW5mbyI6InhWYUVzNk5ybE95N0poeVJMTWN1WnEyZjJCRmFtTm5VL0hyQUpmaCtCWTBIeGpDNWhjUjBldzJWTFRielRHQnl0RzdxQkFwb3cxTUR3ZVVjYUVrUy80RC9YdnJCKzdNaHZFdDZPS0laVXk0PSIsImV4cCI6MTgwOTAxMDgwMCwianRpIjoiQjUxODA0MzFDRUQxNEFCMjkzNTYxMDEyMTlGMTRBQ0UifQ.8oPA14nygH79FFUsbSOdk4MJUWm7aafjaSm4duVpZ6WGbGKcIJIFHxgoYm7NoBO9XqWTfAgDwV_TOpKqOExYqA";

            // 부서 관리용 reqeust parameter
            String orgApiParam = "{\n" +
                    "  \"params\": {\n" +
                    "        \"VS_ORG_CODE\": \"TEST_SUB\"\n" +
                    "      , \"VS_ORG_NAME\": \"TEST하위\"\n" +
                    "      , \"VS_PARENT_CODE\": \"TEST\"\n" +
                    "  }\n" +
                    "  , \"reportCode\": \"REP2809A1EB401644D9A542A28D4F779BAF\"\n" +
                    "  , \"serverScriptCode\": \"ORG_SAVE\"\n" +
                    "}";

            // 사용자 관리용 request parameter
            String userApiParam = "{\n" +
                    "  \"params\": {\n" +
                    "        \"VS_USER_CODE\": \"no5\"\n" +
                    "      , \"VS_USER_NAME\": \"5번사용자\"\n" +
                    "      , \"VS_ORG_CODE\": \"TEST\"\n" +
                    "  }\n" +
                    "  , \"reportCode\": \"REP2809A1EB401644D9A542A28D4F779BAF\"\n" +
                    "  , \"serverScriptCode\": \"USER_SAVE\"\n" +
                    "}";

            String rspData = execute(restApiUrl , userApiParam , null);

            System.out.println("rspData by aud : "+rspData);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /* SSL을 사용일 경우 (https) */
    private static SSLContext getSslContext() throws Exception{
        SSLContext sslCTX = null;
        // TrustManager
        TrustManager[] trustManagers = null;
        trustManagers = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        //return new X509Certificate[0];
                        return null;
                    }
                }
        };
        // SSL context
        sslCTX = SSLContext.getInstance("TLS");
        sslCTX.init(null, trustManagers, new java.security.SecureRandom());
        return sslCTX;
    }

    private static String execute(String targetURL, String data, Map<String, String> requestHeaders) throws  Exception{
        String token = "Bearer " + apAccessToken; // Bearer 다음에 공백 추가

        HttpURLConnection con = null;
        BufferedReader bufferReader = null;
        OutputStream outStream = null;
        try{
            URL url = null ;
            try{
                url = new URL(null,targetURL);
            }catch(ClassCastException classCastException){
                // weblogic의 경우에 HttpConnection 사용하지 않고 weblogic.net.http.SOAPHttpsURLConnection 사용
                url = new URL(targetURL);
            }

            boolean isSecure = targetURL.toLowerCase().startsWith("https:");
            if(isSecure){
                // https 연결
                con = (HttpsURLConnection)url.openConnection();
                SSLContext sslContext = getSslContext();
                if(sslContext != null){
                    ((HttpsURLConnection)con).setSSLSocketFactory(sslContext.getSocketFactory());
                }
            }else{
                con = (HttpURLConnection)url.openConnection();
            }

            con.setConnectTimeout(10 * 1000);
            con.setReadTimeout(10 * 1000);
            con.setRequestMethod("POST");
            con.setRequestProperty("Accept-Charset", "UTF-8");
            con.setRequestProperty("Authorization" , token);
            con.setRequestProperty("Content-Type", "application/json");
            con.setRequestProperty("charset", "utf-8");

            if (requestHeaders != null){
                for(Map.Entry<String, String> header :requestHeaders.entrySet()) {
                    con.setRequestProperty(header.getKey(), header.getValue());
                }
            }

            con.setDoInput(true);// 응답 헤더와 메시지를 읽어들이겠다는 옵션
            con.setUseCaches(false);
            con.setDefaultUseCaches(false);

            con.setDoOutput(true); //OutputStream으로 POST 데이터를 넘겨주겠다는 옵션
            outStream = con.getOutputStream();

            outStream.write(data.getBytes("UTF-8"));
            outStream.flush();
            outStream.close();

            //응답 결과
            if(con.getResponseCode() != 200 && con.getResponseCode() != 201){
                throw new  java.lang.Exception("HTTP Error("+con.getResponseCode() +")" + targetURL);
            }

            if(con.getContentType() != null && con.getContentType().toUpperCase().indexOf("EUC-KR") != -1){
                bufferReader = new BufferedReader( new InputStreamReader( con.getInputStream(), "EUC-KR" ) );
            }
            else{
                bufferReader = new BufferedReader( new InputStreamReader( con.getInputStream(), "UTF-8" ) );
            }

            // 응답 header check
            apAccessToken = con.getHeaderField("bimatrix_ap_accessToken");

            String inputText = "";
            StringBuilder sbText = new StringBuilder();
            while ((inputText = bufferReader.readLine()) != null) {
                if(sbText.length() > 0)
                    sbText.append(inputText + "\r\n");
                else
                    sbText.append(inputText);
            }
            bufferReader.close();
            bufferReader = null;

            if(con != null){ try{ con.disconnect(); }catch(Exception ex){ } }
            return sbText.toString();

        } catch (Exception e) {
            if(con != null){ try{ con.disconnect(); }catch(Exception ex){ } }
            throw e;
        }
    }

}
