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

import com.jscape.util.SuppressObfuscation;

import java.net.InetAddress;
import java.security.PublicKey;

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

/**
 * Provides services for verifying server host key.
 *
 * @author Alex Usun
 */
public interface HostKeyVerificationService {

    /**
     * Represents a service which does no verification.
     */
    HostKeyVerificationService NULL = new HostKeyVerificationService() {
        @Override
        public void assertKeyValid(InetAddress host, PublicKey key) {
            // empty
        }
    };

    /**
     * Checks if specified key is valid.
     *
     * @param host a server host
     * @param key a server key
     *
     * @throws OperationException if an error occurs
     */
    void assertKeyValid(InetAddress host, PublicKey key)
            throws OperationException;

    /**
     * Represents operation error.
     */
    @SuppressObfuscation
    class OperationException
            extends Exception {

        private static final long serialVersionUID = -8196168395850634791L;

        public static OperationException wrap(Throwable e) {
            return e instanceof OperationException ? (OperationException) e : new OperationException(e);
        }

        public OperationException() {
        }

        public OperationException(String message) {
            super(message);
        }

        public OperationException(String message, Throwable cause) {
            super(message, cause);
        }

        public OperationException(Throwable cause) {
            super(cause.getMessage() != null ? cause.getMessage() : cause.toString(), cause);
        }

    }

    /**
     * Represents a verification failure.
     */
    @SuppressObfuscation
    class InvalidHostKeyException
            extends OperationException {

        private static final long serialVersionUID = 1361814658990574111L;

        public final InetAddress host;
        public final PublicKey key;

        public InvalidHostKeyException(InetAddress host, PublicKey key) {
            super("Invalid host key.");

            assertNotNull(host);
            this.host = host;

            assertNotNull(key);
            this.key = key;
        }
    }
}
