package com.jscape.inet.ssh.protocol.v2.authentication;

import com.jscape.inet.ssh.protocol.v2.transport.TransportConnection;

import java.util.Arrays;
import java.util.List;

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

/**
 * Component SSH client authentication operation. Represents a container for multi-stage authentications.
 *
 * @author Alex Usun
 */
public class ComponentClientAuthentication
        implements ClientAuthentication {

    private final List<ClientAuthentication> authentications;

    /**
     * Creates a new operation instance.
     *
     * @param authentications authentications
     */
    public ComponentClientAuthentication(List<ClientAuthentication> authentications) {
        assertNotNull(authentications);
        this.authentications = authentications;
    }

    /**
     * Creates a new operation instance.
     *
     * @param authentications authentications
     */
    @SuppressWarnings("unchecked")
    public ComponentClientAuthentication(ClientAuthentication... authentications) {
        this(Arrays.asList(authentications));
    }

    @Override
    public void applyTo(TransportConnection connection, String serviceName)
            throws Exception {
        Exception error = null;

        for (ClientAuthentication authentication : this.authentications) {
            try {
                authentication.applyTo(connection, serviceName);
                return;
            } catch (PartialSuccessException e) {
                // ok
            } catch (Exception e) {
                error = e;
            }
        }

        throw error;
    }

    /**
     * Returns authentications.
     *
     * @return authentications
     */
    public List<ClientAuthentication> authentications() {
        return this.authentications;
    }

    @Override
    public String toString() {
        return "ComponentClientAuthentication {"
               + "authentications=" + this.authentications
               + '}';
    }
}
