package com.abbidot.baselibrary.util.rsa;

import com.abbidot.baselibrary.util.LogUtil;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;


public class Digest {
    private static final String ENCODE = "UTF-8";

    private String signMD5(String aValue, String encoding) {
        try {
            byte[] input = aValue.getBytes(encoding);
            MessageDigest md = MessageDigest.getInstance("MD5");
            return toHex(md.digest(input));
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            LogUtil.Companion.e("signMD5 Exception" + e.getMessage());
            return null;
        }
    }

    private String hmacSign(String aValue) {
        try {
            byte[] input = aValue.getBytes();
            MessageDigest md = MessageDigest.getInstance("MD5");
            return toHex(md.digest(input));
        } catch (NoSuchAlgorithmException e) {
            LogUtil.Companion.e(e.getMessage());
            return null;
        }
    }

    private String hmacSign(String aValue, String aKey) {
        return hmacSign(aValue, aKey, ENCODE);
    }

    public static String hmacSign(String aValue, String aKey, String encoding) {
        byte[] k_ipad = new byte[64];
        byte[] k_opad = new byte[64];
        byte[] keyb;
        byte[] value;
        try {
            keyb = aKey.getBytes(encoding);
            value = aValue.getBytes(encoding);
        } catch (UnsupportedEncodingException e) {
            keyb = aKey.getBytes();
            value = aValue.getBytes();
        }
        Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
        Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
        for (int i = 0; i < keyb.length; i++) {
            k_ipad[i] = (byte) (keyb[i] ^ 0x36);
            k_opad[i] = (byte) (keyb[i] ^ 0x5c);
        }

        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            LogUtil.Companion.e("hmacSign Exception:" + e.getMessage());
            return null;
        }
        md.update(k_ipad);
        md.update(value);
        byte[] dg = md.digest();
        md.reset();
        md.update(k_opad);
        md.update(dg, 0, 16);
        dg = md.digest();
        return toHex(dg);
    }

    private String hmacSHASign(String aValue, String aKey, String encoding) {
        byte[] k_ipad = new byte[64];
        byte[] k_opad = new byte[64];
        byte[] keyb;
        byte[] value;
        try {
            keyb = aKey.getBytes(encoding);
            value = aValue.getBytes(encoding);
        } catch (UnsupportedEncodingException e) {
            keyb = aKey.getBytes();
            value = aValue.getBytes();
        }
        Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
        Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
        for (int i = 0; i < keyb.length; i++) {
            k_ipad[i] = (byte) (keyb[i] ^ 0x36);
            k_opad[i] = (byte) (keyb[i] ^ 0x5c);
        }

        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException e) {
            LogUtil.Companion.e("hmacSHASign Exception:" + e.getMessage());
            return null;
        }
        md.update(k_ipad);
        md.update(value);
        byte[] dg = md.digest();
        md.reset();
        md.update(k_opad);
        md.update(dg, 0, 20);
        dg = md.digest();
        return toHex(dg);
    }

    public static String digest(String aValue) {
        return digest(aValue, ENCODE);
    }

    public static String digest(String aValue, String encoding) {
        aValue = aValue.trim();
        byte[] value;
        try {
            value = aValue.getBytes(encoding);
        } catch (UnsupportedEncodingException e) {
            value = aValue.getBytes();
        }
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException e) {
            LogUtil.Companion.e("digest Exception:" + e.getMessage());
            return null;
        }
        return toHex(md.digest(value));
    }


    private String digest(String aValue, String alg, String encoding) {
        aValue = aValue.trim();
        byte[] value;
        try {
            value = aValue.getBytes(encoding);
        } catch (UnsupportedEncodingException e) {
            value = aValue.getBytes();
        }
        MessageDigest md;
        try {
            md = MessageDigest.getInstance(alg);
        } catch (NoSuchAlgorithmException e) {
            LogUtil.Companion.e("digest Exception:" + e.getMessage());
            return null;
        }
        return toHex(md.digest(value));
    }

    private String udpSign(String aValue) {
        try {
            byte[] input = aValue.getBytes(StandardCharsets.UTF_8);
            MessageDigest md = MessageDigest.getInstance("SHA1");
            return new String(Base64.encode(md.digest(input)), ENCODE);
        } catch (Exception e) {
            return null;
        }
    }

    private static String toHex(byte[] input) {
        if (input == null)
            return null;
        StringBuilder output = new StringBuilder(input.length * 2);
        for (byte b : input) {
            int current = b & 0xff;
            if (current < 16)
                output.append("0");
            output.append(Integer.toString(current, 16));
        }
        return output.toString();
    }

}
