package com.jscape.inet.ssh.util;

import com.jscape.crypto.MD5;
import com.jscape.util.Base64Format;
import com.jscape.util.HexFormat;
import com.jscape.util.keystore.SshPublicKeyCodec;

import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.PublicKey;

/**
 * OpenSSH-compliant key fingerprint formatter.
 * Formats key fingerprint as ':'-separated two-digit hex values:
 * "18:bc:ec:a5:0f:9a:fc:1a:60:96:7a:17:c8:ed:73:ac".
 *
 * @author Alex
 */
public class KeyFingerprintFormat {

    private static final SshPublicKeyCodec KEY_WRITER = new SshPublicKeyCodec(null);

    public static String format(PublicKey key) {
        byte[] fingerprint = md5HashOf(key);
        return HexFormat.formatData(fingerprint, ":");
    }

    public static byte[] md5HashOf(PublicKey key) {
        try {
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            KEY_WRITER.write(key, buffer);
            return MD5.defaultHash().compute(buffer.toByteArray());
        } catch (Exception e) {
            throw new IllegalArgumentException("Unsupported key type.");
        }
    }

    public static byte[] parseMd5(String data) {
        return HexFormat.parseData(data, ":");
    }

    public static String formatSha256(PublicKey key) {
        byte[] fingerprint = sha256HashOf(key);
        return String.format("SHA256:%s", Base64Format.formatData(fingerprint));
    }

    public static byte[] sha256HashOf(PublicKey key) {
        try {
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            KEY_WRITER.write(key, buffer);
            return MessageDigest.getInstance("SHA256").digest(buffer.toByteArray());
        } catch (Exception e) {
            throw new IllegalArgumentException("Unsupported key type.");
        }
    }

    public static byte[] parseSha256(String data) {
        return Base64Format.parseData(data.startsWith("SHA256:") ?  data.substring(7) : data);
    }

    private KeyFingerprintFormat() {
        // empty
    }
}
