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

import com.jscape.inet.ssh.protocol.messages.Message;
import com.jscape.inet.ssh.protocol.v2.marshaling.MessageCodec;
import com.jscape.inet.ssh.protocol.v2.messages.SshMsgUserAuthRequestPassword;
import com.jscape.inet.ssh.protocol.v2.transport.TransportConnection;

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

/**
 * Represents a SSH 'password' authentication operation.
 *
 * @author Alex Usun
 */
public class PasswordClientAuthentication
        extends AbstractClientAuthentication {

    private String username;
    private String password;

    public static PasswordClientAuthentication defaultAuthentication(String username, String password) {
        return new PasswordClientAuthentication(PasswordAuthenticationMessages.defaultMessages(), username, password);
    }

    /**
     * Creates a new operation instance.
     *
     * @param username an username
     * @param password a password
     */
    public PasswordClientAuthentication(MessageCodec.Factory codecFactory, String username, String password) {
        super(codecFactory);

        assertNotNull(username);
        this.username = username;

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

    public void updateUsername(String value) {
        assertNotNull(value);
        this.username = value;
    }

    public void updatePassword(String value) {
        assertNotNull(value);
        this.password = value;
    }

    @Override
    public void applyTo(TransportConnection connection, String serviceName)
            throws Exception {
        init(connection);
        sendPassword(connection, serviceName);
    }

    @Override
    public String toString() {
        return "PasswordAuthenticationOperation {"
                + "username='" + this.username + '\''
                + ", password='*****'"
                + ", banner='" + this.banner + '\''
                + ", bannerLanguageTag='" + this.bannerLanguageTag + '\''
                + '}';
    }

    protected void init(TransportConnection connection) {
        super.init(connection);
        this.codecFactory.update(connection.session().messageCodec);
    }

    private void sendPassword(TransportConnection connection, String serviceName)
            throws Exception {
        connection.write(new SshMsgUserAuthRequestPassword(this.username, serviceName, this.password));
        Message response = receive(connection);
        assertSuccess(response);
    }

}
