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.Provider;
import java.security.PublicKey;

/**
 * @author Alex Usun
 */
public class SshPublicKeyCodec
        implements DataCodec<PublicKey> {

    private final Provider provider;

    public static PublicKey readValue(InputStream in, Provider provider)
            throws IOException {
        byte[] data = IOTools.readFully(in);
        return DataTools.read(new MemorySource(data),
                              new SshRsaPublicKeyCodec(provider),
                              new SshDsaPublicKeyCodec(provider),
                              new SshEcPublicKeyCodec(provider));
    }

    public static void writeValue(PublicKey value, OutputStream out)
            throws IOException {
        MemorySource source = new MemorySource();
        DataTools.write(value, source,
                        SshRsaPublicKeyCodec.bcCodec(),
                        SshDsaPublicKeyCodec.bcCodec(),
                        SshEcPublicKeyCodec.bcCodec());
        out.write(source.buffer());
    }

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

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

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

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

    public void write(PublicKey value, OutputStream out)
            throws IOException {
        writeValue(value, out);
    }
}