package api.wsit.product_request;

import static api.wsit.product_request.execute.ApiRequestExecutor.execute;
import static api.wsit.product_request.execute.ApiSchema.getRequestContentPath;


import api.wsit.product_request.execute.ApiSchema;
import config.product.ProductTypeEnum;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;

public class DocumentManagement {

    public static final String API_PRODUCT_CATEGORY = "File Upload";
    public static final String API_FOLDER = "/bank-guarantee";


    public static class V3 extends ApiSchema.Edge {
        public static final String API_VERSION = "V3";

        public static class SubmitDocuments {
            public static final String API_NAME = "Submit Documents";
            public static final String HTTP_METHOD = HttpPost.METHOD_NAME;
            public static final HashMap<String, String> REQUEST_URI_PARAMETERS = new HashMap<String, String>();
            public static final HashMap<String, String> ADDITIONAL_REQUEST_HEADERS = new HashMap<String, String>();
            public static List<File> attachedFiles = getAttachments();
            public static HashMap<String, Object> ATTACH_DOCUMENT = new HashMap<String, Object>() {
                {
                    put("attachDocument", attachedFiles);
                }
            };
            public static HashMap<String, Object> ADDITIONAL_TOKEN_CLAIMS = new HashMap<String, Object>() {
                {
                    put("claimsNoEncrypt", new HashMap<String, Object>() {
                        {
                            put("checksum", getCheckSum());
                            put("productType", ProductTypeEnum.TL.getType());
                        }
                    });
                    put("claimsToEncrypt", new HashMap<String, Object>(){
                        {
                            put("accountNumber", "HKHSBC002253474120");
                        }
                    });
                }
            };
            public static final HashMap<String, String> PAYLOAD_WRAPPERS = new HashMap<String, String>() {
                {
                    put("request", "encryptedRequestBase64");
                    put("response", "encryptedResponseBase64");
                }
            };
            public static final HashMap<String, String> API_ENDPOINT_URLS = new HashMap<String, String>() {
                {
                    put("SANDBOX", null);
                    put("UAT",  "/cmb-gtrf-mkt-pa-file-mgr-sit-external-proxy/v3/supporting-files");
                    put("PRODUCTION", "");

                }
            };
            public static HashMap API_SETTINGS = new HashMap<String, Object>() {
                {
                    put("apiProductCategory", API_PRODUCT_CATEGORY);
                    put("apiVersion", API_VERSION);
                    put("apiName", API_NAME);
                    put("httpMethod", HTTP_METHOD);
                    put("apiEndpointUrls", API_ENDPOINT_URLS);
                    put("apiSchema", SCHEMA_NAME);
                    put("requestUriParameters", REQUEST_URI_PARAMETERS);
                    put("additionalTokenClaims",ADDITIONAL_TOKEN_CLAIMS);
                    put("contentType", ContentType.MULTIPART_FORM_DATA.getMimeType());
                    put("additionalRequestHeaders", ADDITIONAL_REQUEST_HEADERS);
                    put("requestAttachment", ATTACH_DOCUMENT);
                    put("xHsbcCryptoSignature", X_HSBC_CRYPTO_SIGNATURE);
                    put("payloadWrappers", PAYLOAD_WRAPPERS);
                }
            };

            public SubmitDocuments() {
            }
            private static String bytesToHex(byte[] bytes) {
                StringBuilder sb = new StringBuilder();
                for (byte b : bytes) {
                    sb.append(String.format("%02x", b));
                }
                return sb.toString();
            }

            public static byte[] multStreamMessageDigest(List<File> attachedFiles)
                throws NoSuchAlgorithmException, IOException {
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
                ByteBuffer bf = ByteBuffer.allocate(8192);
                for (File file : attachedFiles) {
                    FileChannel fileChannel = new FileInputStream(file).getChannel();
                    while ((fileChannel.read(bf)) != -1) {
                        bf.flip();
                        digest.update(bf);
                        bf.clear();
                    }
                }
                return digest.digest();
            }

            public static List<File> getAttachments() {
                List<File> attachedFiles = new ArrayList<>();
                Path startPath = Paths.get("src/main/resources/attachments");
                try {
                    Files.walk(startPath)
                        .filter(Files::isRegularFile)
                        .forEach(filePath -> attachedFiles.add(filePath.toFile()));
                    return attachedFiles;
                } catch (Exception e) {
                    System.out.println("generate files checksum error:" + e);
                }
                return null;
            }

            public static String getCheckSum() {
                try {
                    return bytesToHex(multStreamMessageDigest(attachedFiles));
                } catch (Exception e) {
                   System.out.println("generate files checksum error:" + e);
                }
                return "";
            }

            public static void main(String[] args) {
                try {
                    execute(API_SETTINGS);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
        public static class QueryDocuments {
            public static final String API_NAME = "Enquire Documents";
            public static final String HTTP_METHOD = HttpGet.METHOD_NAME;
            public static final HashMap<String, String> REQUEST_URI_PARAMETERS = new HashMap<String, String>() {
                {
                    put("docUploadRequestId", "11e1faf15ada48d59c4d7cadfcc41b1c");

                }
            };
            public static final HashMap<String, String> ADDITIONAL_REQUEST_HEADERS = new HashMap<String, String>();
            public static final String REQUEST_JSON_FILE = null;
            public static HashMap<String, Object> ADDITIONAL_TOKEN_CLAIMS = new HashMap<String, Object>() {
                {
                    put("claimsToEncrypt", new HashMap<String, Object>(){
                        {
                            put("accountNumber", "HKHSBC002253474120");
                        }
                    });
                }
            };
            public static final HashMap<String, String> PAYLOAD_WRAPPERS = new HashMap<String, String>() {
                {
                    put("request", "encryptedRequestBase64");
                    put("response", "encryptedResponseBase64");
                }
            };
            public static final HashMap<String, String> API_ENDPOINT_URLS = new HashMap<String, String>() {
                {
                    put("SANDBOX", null);
                    put("UAT",  "/cmb-gtrf-mkt-pa-file-mgr-sit-external-proxy/v3/supporting-files");
                    put("PRODUCTION", "");

                }
            };
            public static HashMap API_SETTINGS = new HashMap<String, Object>() {
                {
                    put("apiProductCategory", API_PRODUCT_CATEGORY);
                    put("apiVersion", API_VERSION);
                    put("apiName", API_NAME);
                    put("httpMethod", HTTP_METHOD);
                    put("apiEndpointUrls", API_ENDPOINT_URLS);
                    put("apiSchema", SCHEMA_NAME);
                    put("requestUriParameters", REQUEST_URI_PARAMETERS);
                    put("additionalTokenClaims",ADDITIONAL_TOKEN_CLAIMS);
                    put("contentType", CONTENT_TYPE);
                    put("additionalRequestHeaders", ADDITIONAL_REQUEST_HEADERS);
                    put("requestJsonFile", REQUEST_JSON_FILE);
                    put("xHsbcCryptoSignature", X_HSBC_CRYPTO_SIGNATURE);
                    put("payloadWrappers", PAYLOAD_WRAPPERS);
                }
            };

            public QueryDocuments() {
            }

            public static void main(String[] args) {
                try {
                    execute(API_SETTINGS);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

}

