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

import com.jscape.inet.ssh.protocol.messages.Message;
import com.jscape.inet.ssh.protocol.v2.marshaling.primitive.StringCodec;
import com.jscape.inet.ssh.protocol.v2.marshaling.primitive.Uint32Codec;
import com.jscape.inet.ssh.protocol.v2.messages.SshMsgUserAuthInfoRequest;
import com.jscape.inet.ssh.protocol.v2.messages.UserAuthInfoRequestPrompt;
import com.jscape.util.io.DataCodec;
import com.jscape.util.io.primitive.BooleanCodec;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Alex Usun
 */
public class SshMsgUserAuthInfoRequestCodec
        implements DataCodec<Message> {

    @Override
    public Message read(InputStream in)
            throws IOException {
        String name = StringCodec.readUtf8Value(in);
        String instruction = StringCodec.readUtf8Value(in);
        String languageTag = StringCodec.readUsAsciiValue(in);
        List<UserAuthInfoRequestPrompt> prompts = readPrompts(in);

        return new SshMsgUserAuthInfoRequest(name, instruction, languageTag, prompts);
    }

    @Override
    public void write(Message value, OutputStream out)
            throws IOException {
        SshMsgUserAuthInfoRequest message = (SshMsgUserAuthInfoRequest) value;
        StringCodec.writeUtf8Value(message.name, out);
        StringCodec.writeUtf8Value(message.instruction, out);
        StringCodec.writeUsAsciiValue(message.languageTag, out);
        writePrompts(message.prompts, out);
    }

    public static List<UserAuthInfoRequestPrompt> readPrompts(InputStream in)
            throws IOException {
        int numPrompts = Uint32Codec.readValue(in);
        List<UserAuthInfoRequestPrompt> prompts = new ArrayList<UserAuthInfoRequestPrompt>(numPrompts);
        for (int i = 0; i < numPrompts; ++i) {
            UserAuthInfoRequestPrompt prompt = readPrompt(in);
            prompts.add(prompt);
        }

        return prompts;
    }

    private void writePrompts(List<UserAuthInfoRequestPrompt> prompts, OutputStream out)
            throws IOException {
        Uint32Codec.writeValue(prompts.size(), out);
        for (UserAuthInfoRequestPrompt prompt : prompts) {
            writePrompt(prompt, out);
        }
    }

    private static UserAuthInfoRequestPrompt readPrompt(InputStream in)
            throws IOException {
        String prompt = StringCodec.readUtf8Value(in);
        boolean echo = BooleanCodec.readValue(in);

        return new UserAuthInfoRequestPrompt(prompt, echo);
    }

    private void writePrompt(UserAuthInfoRequestPrompt prompt, OutputStream out)
            throws IOException {
        StringCodec.writeUtf8Value(prompt.prompt, out);
        BooleanCodec.writeValue(prompt.echo, out);
    }
}
