package com.jscape.inet.ssh.protocol.v2.transport.keyexchange;

import com.jscape.inet.ssh.protocol.v2.marshaling.*;
import com.jscape.inet.ssh.protocol.v2.marshaling.keys.PublicKeyCodec;
import com.jscape.inet.ssh.protocol.v2.marshaling.keys.PublicKeyCodecs;
import com.jscape.inet.ssh.protocol.v2.marshaling.keys.SignatureCodec;
import com.jscape.inet.ssh.protocol.v2.marshaling.keys.SignatureCodecs;
import com.jscape.inet.ssh.protocol.v2.messages.*;
import com.jscape.util.crypto.CryptoServicesProvider;
import com.jscape.util.io.DataCodec;

import java.security.Provider;
import java.security.PublicKey;

import static com.jscape.util.Parameters.assertNotNull;

/**
 * @author Alex Usun
 */
public class DiffieHellmanKeyGroupExchangeMessages
        implements MessageCodec.Factory {

    private final MessageCodec.Entry[] entries;

    public static DiffieHellmanKeyGroupExchangeMessages defaultMessages() {
        return defaultMessages(CryptoServicesProvider.instance());
    }

    public static DiffieHellmanKeyGroupExchangeMessages defaultMessages(String provider) {
        DataCodec<PublicKey> publicKeyCodec = PublicKeyCodecs.init(new PublicKeyCodec(), provider);
        DataCodec<Signature> signatureCodec = SignatureCodecs.init(new SignatureCodec());

        return new DiffieHellmanKeyGroupExchangeMessages(new MessageCodec.Entry(30, new SshMsgKexDhGexRequestOldCodec(), SshMsgKexDhGexRequestOld.class),
                                                         new MessageCodec.Entry(34, new SshMsgKexDhGexRequestCodec(), SshMsgKexDhGexRequest.class),
                                                         new MessageCodec.Entry(31, new SshMsgKexDhGexGroupCodec(), SshMsgKexDhGexGroup.class),
                                                         new MessageCodec.Entry(32, new SshMsgKexDhGexInitCodec(), SshMsgKexDhGexInit.class),
                                                         new MessageCodec.Entry(33, new SshMsgKexDhGexReplyCodec(publicKeyCodec, signatureCodec), SshMsgKexDhGexReply.class));
    }

    public static DiffieHellmanKeyGroupExchangeMessages defaultMessages(Provider provider) {
        DataCodec<PublicKey> publicKeyCodec = PublicKeyCodecs.init(new PublicKeyCodec(), provider);
        DataCodec<Signature> signatureCodec = SignatureCodecs.init(new SignatureCodec());

        return new DiffieHellmanKeyGroupExchangeMessages(new MessageCodec.Entry(30, new SshMsgKexDhGexRequestOldCodec(), SshMsgKexDhGexRequestOld.class),
                                                         new MessageCodec.Entry(34, new SshMsgKexDhGexRequestCodec(), SshMsgKexDhGexRequest.class),
                                                         new MessageCodec.Entry(31, new SshMsgKexDhGexGroupCodec(), SshMsgKexDhGexGroup.class),
                                                         new MessageCodec.Entry(32, new SshMsgKexDhGexInitCodec(), SshMsgKexDhGexInit.class),
                                                         new MessageCodec.Entry(33, new SshMsgKexDhGexReplyCodec(publicKeyCodec, signatureCodec), SshMsgKexDhGexReply.class));
    }

    public DiffieHellmanKeyGroupExchangeMessages(MessageCodec.Entry... entries) {
        assertNotNull(entries);
        this.entries = entries;
    }

    @Override
    public MessageCodec update(MessageCodec codec) {
        return codec.set(this.entries);
    }
}
