package com.jscape.util.keystore;

import com.jscape.util.IOTools;
import com.jscape.util.crypto.CryptoServicesProvider;
import com.jscape.util.io.DataCodec;
import com.jscape.util.io.DataTools;
import com.jscape.util.io.MemorySource;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyPair;
import java.security.Provider;

/**
 * @author Alex Usun
 */
public class Pkcs8KeyPairCodec
        implements DataCodec<KeyPair> {

    private final Provider provider;

    public static KeyPair readValue(InputStream in, Provider provider)
            throws IOException {
        byte[] data = IOTools.readFully(in);
        return DataTools.read(new MemorySource(data),
                              new Pkcs8RsaKeyPairCodec(provider),
                              new Pkcs8DsaKeyPairCodec(provider),
                              new Pkcs8EcKeyPairCodec());
    }

    public static void writeValue(KeyPair value, OutputStream out)
            throws IOException {
        MemorySource source = new MemorySource();
        DataTools.write(value, source, Pkcs8RsaKeyPairCodec.bcCodec(), Pkcs8DsaKeyPairCodec.bcCodec(), Pkcs8EcKeyPairCodec.defaultCodec());
        out.write(source.buffer());
    }

    public static Pkcs8KeyPairCodec defaultCodec() {
        return new Pkcs8KeyPairCodec(null);
    }

    public static Pkcs8KeyPairCodec bcCodec() {
        return new Pkcs8KeyPairCodec(CryptoServicesProvider.instance());
    }

    public Pkcs8KeyPairCodec(Provider provider) {
        this.provider = provider;
    }

    @Override
    public KeyPair read(InputStream in)
            throws IOException {
        return readValue(in, this.provider);
    }

    @Override
    public void write(KeyPair value, OutputStream out)
            throws IOException {
        writeValue(value, out);
    }
}
