package api.wsit.request_helper;
/*
 * ***************************************************************
 * , Copyright. HSBC Holdings plc ccyy ALL RIGHTS RESERVED.
 *
 * This software is only to be used for the purpose for which it
 * has been provided. No part of it is to be reproduced,
 * disassembled, transmitted, stored in a retrieval system or
 * translated in any human or computer language in any way or
 * for any other purposes whatsoever without the prior written
 * consent of HSBC Holdings plc.
 * ***************************************************************
 */

import config.ClientConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import util.Projects;
import api.wsit.product_request.execute.ApiSchema;

import java.security.Security;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static security.AuthUtility.generateAuthTokens;
import static security.KeyUtility.*;
import static util.HttpClientUtil.generateRequestHeaders;
import static util.JsonUtil.getJsonObjectFromFile;
import static api.wsit.request_helper.WsitApiRequest.generateRequestPayload;


public class EncryptAndGenerateAuthToken {

    /**
     * used to fix java.security.NoSuchProviderException: no such provider: BC
     */
    static {
        try {
            Security.addProvider(new BouncyCastleProvider());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public EncryptAndGenerateAuthToken() {
    }

    public static void main(String[] args) {
        System.out.println("----- #Start of API Sample Code Steps# -----");
        HashMap<String, String> activeProjectSettings = Projects.LoadActiveProjectSettings();
        String httpMethod = HttpPost.METHOD_NAME;
        String apiSchema = ApiSchema.Gtrf.SCHEMA_NAME; //Input "EDGE" for API Version >= 3.0.0. Otherwise, for previous version, input "GTRF".
        System.out.println("-----#1. Start of loading Security Credentials-----");
        String bankPgpPublicKeyFile = activeProjectSettings.get("bankPublicKeyFile");
        String clientPgpPrivateKeyFile = activeProjectSettings.get("clientPrivateKeyFile");
        String clientPrivateKeyPassphrase = activeProjectSettings.get("clientPrivateKeyPassphrase"); //passPhrase of your key
        // 1.1 Preparing PGP Keys
        System.out.println("#1.1. Preparing PGP Keys...");
        // 1.1.1 Retrieves Bank PGP Public Keys
        System.out.println("#1.1.1 Retrieving Bank PGP public keys...");
        List<PGPPublicKey> bankPgpPublicKeys = getPublicKeys(bankPgpPublicKeyFile);
        System.out.println("#1.1.2 Setting one of the Bank PGP Public Keys as encryption key...");
        PGPPublicKey bankPgpPublicKey = getEncryptionKey(apiSchema, bankPgpPublicKeys);
        // 1.1.2. Retrieves Client PGP Private Keys
        System.out.println("#1.2.1 Retrieving Client PGP private keys...");
        List<PGPPrivateKey> clientPgpPrivateKeys = getPrivateKeys(clientPgpPrivateKeyFile, clientPrivateKeyPassphrase);
        System.out.println("#1.2.2 Setting one of the Client PGP Private Keys as signature key...");
        PGPPrivateKey clientPgpPrivateKey = clientPgpPrivateKeys.get(0);
        System.out.println("-----End of #1. loading Security Credentials-----\n");

        // 2. Prepare Request Payload
        System.out.println("-----Start of #2. Preparing the HTTP Request Payload...");
        // 2.1 Prepare Request JSON String
        // 2.1 Prepare Request JSON String
        String textToEncrypt = null;
        if (httpMethod != HttpGet.METHOD_NAME) {
            textToEncrypt = getJsonObjectFromFile(ClientConfig.REQUEST_CONTENT_PATH + "/SampleRequestContent.json").toString();
        }
        System.out.println("#2.1. Request Content JSON String: \n" + textToEncrypt);
        HashMap<String, String> payloadWrappers = new HashMap<String, String>();
        Boolean xHsbcCryptoSignature = false;
        switch (apiSchema) {
            case (ApiSchema.Edge.SCHEMA_NAME):
                xHsbcCryptoSignature = true;
                payloadWrappers.put("request", "encryptedRequestBase64");
                payloadWrappers.put("response", "encryptedResponseBase64");
                break;
            case (ApiSchema.Gtrf.SCHEMA_NAME):
                xHsbcCryptoSignature = false;
                payloadWrappers.put("request", null);
                payloadWrappers.put("response", null);
                break;
        }
        // 2.2 Generate Request Payload
        System.out.println("#2.2. Start of Generating Request Payload");
        String requestPayload = generateRequestPayload(httpMethod, payloadWrappers, textToEncrypt, bankPgpPublicKey, clientPgpPrivateKey, xHsbcCryptoSignature);
        System.out.println("-----End of #2. Preparing the HTTP Request Payload...\n");

        // 3. Generate Authorization Token
        System.out.println("-----Start of #3. Generating Authorization Token-----");
        String clientProfileId = activeProjectSettings.get("clientProfileId"); // API Profile ID Bank Assigned to you.
        String oboProfileId = activeProjectSettings.get("oboProfileId"); //Customer's ID on your platform. Input null if you are a Direct Client.
        HashMap<String, Object> additionalTokenClaims = new HashMap<String, Object>();
        Map<String, String> authTokens = generateAuthTokens(httpMethod, apiSchema, clientProfileId, oboProfileId, additionalTokenClaims, requestPayload, bankPgpPublicKey, clientPgpPrivateKey, xHsbcCryptoSignature);
        System.out.println("-----End of of #3. Generating Authorization Token-----\n");

        // 4. Generate Request
        System.out.println("-----Start of #4. Executing API Request-----");
        // 4. Generate Request
        System.out.println("-----Start of #4 Executing API Request-----");
        //4.1 Generate URI Parameters if required:
        HashMap<String, String> requestUriParameters = new HashMap<String, String>() {
            {
                put("paramKey001", "paramValue001"); //Input only if required
            }
        };
        //4.2 Generate Request Headers
        String clientHostingRegion = "SG"; // Your Platform or Business Operating Region, In ISO3166-alpha-2
        HashMap<String, String> additionalRequestHeaders = new HashMap<String, String>() {
            {
                //put("headerKey001", "headerValue001"); //Input only if required
            }
        };
        HashMap<String, String> requestHeaderJson = generateRequestHeaders(httpMethod, apiSchema, authTokens, clientHostingRegion, oboProfileId, xHsbcCryptoSignature, additionalRequestHeaders);
    }


}
