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

import com.jscape.inet.ssh.protocol.messages.Message;
import com.jscape.inet.ssh.protocol.v2.messages.*;
import com.jscape.util.net.connection.MessageConnection;
import com.jscape.util.net.connection.SyncMessageConnection;

import java.util.List;

/**
 * @author Alex Usun
 */
public class SessionChannelConnection
        extends ChannelConnection
        implements SshMsgChannelRequestExitStatus.Handler {

    private Integer exitStatus;

    public SessionChannelConnection(SyncMessageConnection<Message> base,
                                    int localId,
                                    int remoteId,
                                    long localInitialWindowSize,
                                    int localMaxPacketSize,
                                    long remoteInitialWindowSize,
                                    int remoteMaxPacketSize,
                                    boolean closeConfirmationRequired) {
        super(base, localId, remoteId, localInitialWindowSize, localMaxPacketSize, remoteInitialWindowSize, remoteMaxPacketSize, closeConfirmationRequired);
    }

    public void pseudoTerminal(String terminalEnvironmentVariable,
                               int terminalCharactersWidth,
                               int terminalRowsHeight,
                               int terminalPixelsWidth,
                               int terminalPixelsHeight,
                               List<TerminalMode> terminalModes,
                               boolean wantReply)
            throws ConnectionException {
        send(new SshMsgChannelRequestPtyReq(this.remoteId,
                                            wantReply,
                                            terminalEnvironmentVariable,
                                            terminalCharactersWidth,
                                            terminalRowsHeight,
                                            terminalPixelsWidth,
                                            terminalPixelsHeight,
                                            terminalModes));
        processRequestResult(wantReply);
    }

    public void environmentVariable(String name, String value, boolean wantReply)
            throws ConnectionException {
        send(new SshMsgChannelRequestEnv(this.remoteId, wantReply, name, value));
        processRequestResult(wantReply);
    }

    public void shell(boolean wantReply)
            throws ConnectionException {
        send(new SshMsgChannelRequestShell(this.remoteId, wantReply));
        processRequestResult(wantReply);
    }

    public void exec(String command, boolean wantReply)
            throws ConnectionException {
        send(new SshMsgChannelRequestExec(this.remoteId, wantReply, command));
        processRequestResult(wantReply);
    }

    public void subsystem(String subsystemName, boolean wantReply)
            throws ConnectionException {
        send(new SshMsgChannelRequestSubsystem(this.remoteId, wantReply, subsystemName));
        processRequestResult(wantReply);
    }

    public void windowChange(int terminalCharactersWidth,
                             int terminalRowsHeight,
                             int terminalPixelsWidth,
                             int terminalPixelsHeight)
            throws ConnectionException {
        send(new SshMsgChannelRequestWindowChange(this.remoteId,
                                                  terminalCharactersWidth,
                                                  terminalRowsHeight,
                                                  terminalPixelsWidth,
                                                  terminalPixelsHeight));
    }

    public void signal(String signalName)
            throws ConnectionException {
        send(new SshMsgChannelRequestSignal(this.remoteId, signalName));
    }

    public void signal(Signal signal)
            throws ConnectionException {
        signal(signal.code);
    }

    public void breakSignal(int breakLengthMillis, boolean wantReply)
            throws ConnectionException {
        send(new SshMsgChannelRequestBreak(this.remoteId, wantReply, breakLengthMillis));
        processRequestResult(wantReply);
    }

    public Integer exitStatus() {
        return this.exitStatus;
    }

    @Override
    public void handle(SshMsgChannelRequestExitStatus message, MessageConnection<Message> connection) {
        this.exitStatus = message.exitStatus;
    }

}
