/*
 * Copyright (C) 2009 Google Inc.  All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.polo.wire.protobuf;

import com.google.polo.exception.BadSecretException;
import com.google.polo.exception.NoConfigurationException;
import com.google.polo.exception.PoloException;
import com.google.polo.exception.ProtocolErrorException;
import com.google.polo.pairing.PairingContext;
import com.google.polo.pairing.PoloUtil;
import com.google.polo.pairing.message.ConfigurationAckMessage;
import com.google.polo.pairing.message.ConfigurationMessage;
import com.google.polo.pairing.message.EncodingOption;
import com.google.polo.pairing.message.OptionsMessage;
import com.google.polo.pairing.message.PairingRequestAckMessage;
import com.google.polo.pairing.message.PairingRequestMessage;
import com.google.polo.pairing.message.PoloMessage;
import com.google.polo.pairing.message.SecretAckMessage;
import com.google.polo.pairing.message.SecretMessage;
import com.google.polo.wire.PoloWireInterface;
import com.google.polo.wire.protobuf.nano.PoloProto;
import com.google.polo.wire.protobuf.nano.PoloProto.OuterMessage;
import com.google.protobuf.nano.MessageNano;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Implementation of {@link PoloWireInterface} that uses Protocol Buffers for
 * the data representation.
 * <p/>
 * The primary work of this class is to translate Protocol Buffer messages
 * instances (derived from {@link MessageNano} to an internal message
 * instance (derived from {@link PoloMessage}, and vice versa.
 * <p/>
 * The reason we are going through all this trouble, and not using protocol
 * buffer objects directly, is that we'd like to limit the scope of protocol
 * buffers to the wire protocol only.  Some applications may prefer to use
 * a different wire format, where the requirement of adding the protobuf library
 * could be an impediment.
 */
public class ProtobufWireAdapter implements PoloWireInterface {

    /**
     * The output coming from the peer.
     */
    private final InputStream mInputStream;
    /**
     * The input going to the peer.
     */
    private final OutputStream mOutputStream;

    /**
     * Constructor.
     *
     * @param input  the {@link InputStream} from the peer
     * @param output the {@link OutputStream} to the peer
     */
    public ProtobufWireAdapter(InputStream input, OutputStream output) {
        mInputStream = input;
        mOutputStream = output;
    }

    /**
     * Generates a new instance from a {@link PairingContext}.
     *
     * @param context the {@link PairingContext}
     * @return the new instance
     */
    public static ProtobufWireAdapter fromContext(PairingContext context) {
        return new ProtobufWireAdapter(context.getPeerInputStream(),
                context.getPeerOutputStream());
    }

    /**
     * Returns the next message sent over the wire, blocking as necessary.
     */
    public PoloMessage getNextMessage() throws IOException, PoloException {
        return protoToPoloMessage(readNextInnerMessage());
    }

    /**
     * Returns the next message read over the wire, requiring it to be a certain
     * type.
     *
     * @param type the required message type
     * @throws IOException   on error during read
     * @throws PoloException if the wrong message type was read, or on protocol
     *                       error
     */
    public PoloMessage getNextMessage(PoloMessage.PoloMessageType type)
            throws IOException, PoloException {
        PoloMessage message = getNextMessage();
        if (message.getType() != type) {
            throw new PoloException("Wrong message type (wanted " + type +
                    ", got " + message.getType() + ")");
        }
        return message;
    }

    /**
     * Returns the next message seen on the input stream.
     *
     * @return the next OuterMessage read from the wire
     * @throws IOException on error during read
     */
    private OuterMessage readNextOuterMessage() throws IOException, PoloException {
        // Read the preamble (length of payload)
        byte[] preambleBuffer = readBytesBlocking(4);
        int messageLen = (int) PoloUtil.intBigEndianBytesToLong(preambleBuffer);

        // Read the payload (serialized PoloMessage)
        byte[] messageBuffer = readBytesBlocking(messageLen);

        // Decode and return the payload
        OuterMessage message = OuterMessage.parseFrom(messageBuffer);

        if (message.status != OuterMessage.STATUS_OK) {
            throw new ProtocolErrorException();
        }

        return message;
    }

    /**
     * Reads the next inner message from the wire, decoding and handling the outer
     * message in the process.
     *
     * @return a protocol buffer message
     * @throws IOException   on error during read
     * @throws PoloException on protocol error
     */
    private MessageNano readNextInnerMessage()
            throws IOException, PoloException {
        OuterMessage message = readNextOuterMessage();

        byte[] payload = message.payload;

        if (message.type == OuterMessage.MESSAGE_TYPE_OPTIONS) {
            return PoloProto.Options.parseFrom(payload);
        } else if (message.type == OuterMessage.MESSAGE_TYPE_PAIRING_REQUEST) {
            return PoloProto.PairingRequest.parseFrom(payload);
        } else if (message.type == OuterMessage.MESSAGE_TYPE_PAIRING_REQUEST_ACK) {
            return PoloProto.PairingRequestAck.parseFrom(payload);
        } else if (message.type == OuterMessage.MESSAGE_TYPE_CONFIGURATION) {
            return PoloProto.Configuration.parseFrom(payload);
        } else if (message.type == OuterMessage.MESSAGE_TYPE_CONFIGURATION_ACK) {
            return PoloProto.ConfigurationAck.parseFrom(payload);
        } else if (message.type == OuterMessage.MESSAGE_TYPE_SECRET) {
            return PoloProto.Secret.parseFrom(payload);
        } else if (message.type == OuterMessage.MESSAGE_TYPE_SECRET_ACK) {
            return PoloProto.SecretAck.parseFrom(payload);
        }

        throw new IOException("Could not unparse message");
    }

    /**
     * Convenience method to read a fixed number of bytes from the client
     * InputStream, blocking if necessary.
     *
     * @param numBytes the number of bytes to read
     * @return the bytes read
     * @throws IOException on error during read
     */
    private byte[] readBytesBlocking(int numBytes) throws IOException {
        byte[] buf = new byte[numBytes];
        int bytesRead = 0;

        // For an SSLSocket, read() can frequently return zero bytes,
        // or fewer bytes than desired, due to SSL unwrapping and other
        // non-application-data events.
        while (bytesRead < numBytes) {
            int inc = mInputStream.read(buf, bytesRead, numBytes - bytesRead);
            if (inc < 0) {
                throw new IOException("Stream closed while reading.");
            }
            bytesRead += inc;
        }
        return buf;
    }

    /**
     * Wraps an outer message in an inner message.
     *
     * @param message the {@link MessageNano} to wrap
     * @throws PoloException if the message was not well formed
     */
    private OuterMessage wrapInnerMessage(MessageNano message)
            throws PoloException {
        int type;
        if (message instanceof PoloProto.Options) {
            type = OuterMessage.MESSAGE_TYPE_OPTIONS;
        } else if (message instanceof PoloProto.PairingRequest) {
            type = OuterMessage.MESSAGE_TYPE_PAIRING_REQUEST;
        } else if (message instanceof PoloProto.PairingRequestAck) {
            type = OuterMessage.MESSAGE_TYPE_PAIRING_REQUEST_ACK;
        } else if (message instanceof PoloProto.Configuration) {
            type = OuterMessage.MESSAGE_TYPE_CONFIGURATION;
        } else if (message instanceof PoloProto.ConfigurationAck) {
            type = OuterMessage.MESSAGE_TYPE_CONFIGURATION_ACK;
        } else if (message instanceof PoloProto.Secret) {
            type = OuterMessage.MESSAGE_TYPE_SECRET;
        } else if (message instanceof PoloProto.SecretAck) {
            type = OuterMessage.MESSAGE_TYPE_SECRET_ACK;
        } else {
            throw new PoloException("Bad inner message type.");
        }

        // compose outer message
        OuterMessage outerMessage = new OuterMessage();
        outerMessage.status = OuterMessage.STATUS_OK;
        outerMessage.protocolVersion = 1;
        outerMessage.type = type;
        outerMessage.payload = MessageNano.toByteArray(message);
        return outerMessage;
    }

    /**
     * Writes an {@link OuterMessage} to the wire.
     *
     * @param message the message
     * @throws IOException on error during write
     */
    private void writeMessage(OuterMessage message) throws IOException {
        byte[] messageBytes = message.payload;
        int messageLength = messageBytes.length;

        mOutputStream.write(PoloUtil.intToBigEndianIntBytes(messageLength));
        mOutputStream.write(messageBytes);
    }

    /**
     * Writes a new message to the wire.
     */
    public void sendMessage(PoloMessage message)
            throws IOException, PoloException {
        MessageNano pb = poloMessageToProto(message);
        OuterMessage outerMessage = wrapInnerMessage(pb);
        writeMessage(outerMessage);
    }

    /**
     * Sends a new error message to the wire.
     */
    public void sendErrorMessage(Exception e) throws IOException {
        OuterMessage outerMessage = new OuterMessage();
        outerMessage.protocolVersion = 1;

        if (e instanceof NoConfigurationException) {
            outerMessage.status = OuterMessage.STATUS_BAD_CONFIGURATION;
        } else if (e instanceof BadSecretException) {
            outerMessage.status = OuterMessage.STATUS_BAD_SECRET;
        } else {
            outerMessage.status = OuterMessage.STATUS_ERROR;
        }

        writeMessage(outerMessage);
    }

    /**
     * Converts an internal message to the corresponding protocol buffer message.
     *
     * @param poloMessage the internal message
     * @return a new {@link MessageNano} instance
     */
    private MessageNano poloMessageToProto(PoloMessage poloMessage) {
        if (poloMessage instanceof PairingRequestMessage) {
            return toProto((PairingRequestMessage) poloMessage);
        } else if (poloMessage instanceof PairingRequestAckMessage) {
            return toProto((PairingRequestAckMessage) poloMessage);
        } else if (poloMessage instanceof OptionsMessage) {
            return toProto((OptionsMessage) poloMessage);
        } else if (poloMessage instanceof ConfigurationMessage) {
            return toProto((ConfigurationMessage) poloMessage);
        } else if (poloMessage instanceof ConfigurationAckMessage) {
            return toProto((ConfigurationAckMessage) poloMessage);
        } else if (poloMessage instanceof SecretMessage) {
            return toProto((SecretMessage) poloMessage);
        } else if (poloMessage instanceof SecretAckMessage) {
            return toProto((SecretAckMessage) poloMessage);
        }
        return null;
    }

    /**
     * Converts a {@link PairingRequestMessage} to a
     * {@link PoloProto.PairingRequest}.
     */
    private PoloProto.PairingRequest toProto(PairingRequestMessage poloMessage) {
        PoloProto.PairingRequest pairingRequest = new PoloProto.PairingRequest();
        pairingRequest.serviceName = poloMessage.getServiceName();

        if (poloMessage.hasClientName()) {
            pairingRequest.clientName = poloMessage.getClientName();
        }
        return pairingRequest;
    }

    /**
     * Converts a {@link PairingRequestAckMessage} to a
     * {@link PoloProto.PairingRequestAck}.
     */
    private PoloProto.PairingRequestAck toProto(PairingRequestAckMessage poloMessage) {
        PoloProto.PairingRequestAck pairingRequestAck = new PoloProto.PairingRequestAck();
        if (poloMessage.hasServerName()) {
            pairingRequestAck.serverName = poloMessage.getServerName();
        }
        return pairingRequestAck;
    }

    /**
     * Converts a {@link OptionsMessage} to a {@link PoloProto.Options}.
     */
    private PoloProto.Options toProto(OptionsMessage poloMessage) {
        PoloProto.Options options = new PoloProto.Options();

        switch (poloMessage.getProtocolRolePreference()) {
            case DISPLAY_DEVICE:
                options.preferredRole = PoloProto.Options.ROLE_TYPE_INPUT;
                break;
            case INPUT_DEVICE:
                options.preferredRole = PoloProto.Options.ROLE_TYPE_OUTPUT;
                break;
        }

        int i = 0, n = poloMessage.getOutputEncodingSet().size();
        options.outputEncodings = new PoloProto.Options.Encoding[n];
        for (EncodingOption enc : poloMessage.getOutputEncodingSet()) {
            options.outputEncodings[i++] = toProto(enc);
        }

        i = 0;
        n = poloMessage.getInputEncodingSet().size();
        options.inputEncodings = new PoloProto.Options.Encoding[n];
        for (EncodingOption enc : poloMessage.getInputEncodingSet()) {
            options.inputEncodings[i++] = toProto(enc);
        }

        return options;
    }

    /**
     * Converts a {@link ConfigurationMessage} to a
     * {@link PoloProto.Configuration}.
     */
    private PoloProto.Configuration toProto(ConfigurationMessage poloMessage) {
        PoloProto.Configuration configuration = new PoloProto.Configuration();
        configuration.encoding = toProto(poloMessage.getEncoding());
        configuration.clientRole = toProto(poloMessage.getClientRole());
        return configuration;
    }

    /**
     * Converts a {@link EncodingOption} to a {@link PoloProto.Options.Encoding}.
     */
    private PoloProto.Options.Encoding toProto(EncodingOption enc) {
        PoloProto.Options.Encoding encoding = new PoloProto.Options.Encoding();

        switch (enc.getType()) {
            case ENCODING_ALPHANUMERIC:
                encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_ALPHANUMERIC;
                break;
            case ENCODING_HEXADECIMAL:
                encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_HEXADECIMAL;
                break;
            case ENCODING_NUMERIC:
                encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_NUMERIC;
                break;
            case ENCODING_QRCODE:
                encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_QRCODE;
                break;
            default:
                encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_UNKNOWN;
                break;
        }

        encoding.symbolLength = enc.getSymbolLength();
        return encoding;
    }

    /**
     * Converts a {@link OptionsMessage.ProtocolRole} to a
     * {@link PoloProto.Options}.
     */
    private int toProto(OptionsMessage.ProtocolRole role) {
        switch (role) {
            case DISPLAY_DEVICE:
                return PoloProto.Options.ROLE_TYPE_OUTPUT;
            case INPUT_DEVICE:
                return PoloProto.Options.ROLE_TYPE_INPUT;
            default:
                return PoloProto.Options.ROLE_TYPE_UNKNOWN;
        }
    }

    /**
     * Converts a {@link ConfigurationAckMessage} to a
     * {@link PoloProto.ConfigurationAck}.
     */
    private PoloProto.ConfigurationAck toProto(ConfigurationAckMessage poloMessage) {
        PoloProto.ConfigurationAck configurationAck = new PoloProto.ConfigurationAck();
        return configurationAck;
    }

    /**
     * Converts a {@link SecretMessage} to a {@link PoloProto.Secret}.
     */
    private PoloProto.Secret toProto(SecretMessage poloMessage) {
        PoloProto.Secret secret = new PoloProto.Secret();
        secret.secret = poloMessage.getSecret();
        return secret;
    }

    /**
     * Converts a {@link SecretAckMessage} to a {@link PoloProto.SecretAck}.
     */
    private PoloProto.SecretAck toProto(SecretAckMessage poloMessage) {
        PoloProto.SecretAck secretAck = new PoloProto.SecretAck();
        secretAck.secret = poloMessage.getSecret();
        return secretAck;
    }

    //
    // polo -> protocol buffer routines
    //

    /**
     * Converts a protocol buffer message to the corresponding internal
     * message.
     *
     * @param protoMessage the protobuf message to convert
     * @return the new {@link PoloMessage}
     */
    private PoloMessage protoToPoloMessage(MessageNano protoMessage) {
        if (protoMessage instanceof PoloProto.PairingRequest) {
            return fromProto((PoloProto.PairingRequest) protoMessage);
        } else if (protoMessage instanceof PoloProto.PairingRequestAck) {
            return fromProto((PoloProto.PairingRequestAck) protoMessage);
        } else if (protoMessage instanceof PoloProto.Options) {
            return fromProto((PoloProto.Options) protoMessage);
        } else if (protoMessage instanceof PoloProto.Configuration) {
            return fromProto((PoloProto.Configuration) protoMessage);
        } else if (protoMessage instanceof PoloProto.ConfigurationAck) {
            return fromProto((PoloProto.ConfigurationAck) protoMessage);
        } else if (protoMessage instanceof PoloProto.Secret) {
            return fromProto((PoloProto.Secret) protoMessage);
        } else if (protoMessage instanceof PoloProto.SecretAck) {
            return fromProto((PoloProto.SecretAck) protoMessage);
        }
        return null;
    }

    /**
     * Converts a {@link PoloProto.PairingRequest} to a
     * {@link PairingRequestMessage}.
     */
    private PairingRequestMessage fromProto(PoloProto.PairingRequest protoMessage) {
        return new PairingRequestMessage(protoMessage.serviceName, protoMessage.clientName);
    }

    /**
     * Converts a {@link PoloProto.PairingRequestAck} to a
     * {@link PairingRequestAckMessage}.
     */
    private PairingRequestAckMessage fromProto(PoloProto.PairingRequestAck protoMessage) {
        return new PairingRequestAckMessage(protoMessage.serverName);
    }

    /**
     * Converts a {@link PoloProto.Options} to a {@link OptionsMessage}.
     */
    private OptionsMessage fromProto(PoloProto.Options protoMessage) {
        OptionsMessage optionsMessage = new OptionsMessage();

        switch (protoMessage.preferredRole) {
            case PoloProto.Options.ROLE_TYPE_INPUT:
                optionsMessage.setProtocolRolePreference(OptionsMessage.ProtocolRole.INPUT_DEVICE);
                break;
            case PoloProto.Options.ROLE_TYPE_OUTPUT:
                optionsMessage.setProtocolRolePreference(OptionsMessage.ProtocolRole.DISPLAY_DEVICE);
                break;
        }

        for (PoloProto.Options.Encoding e : protoMessage.inputEncodings) {
            optionsMessage.addInputEncoding(fromProto(e));
        }

        for (PoloProto.Options.Encoding e : protoMessage.outputEncodings) {
            optionsMessage.addOutputEncoding(fromProto(e));
        }

        return optionsMessage;
    }

    /**
     * Converts a {@link PoloProto.Configuration} to a
     * {@link ConfigurationMessage}.
     */
    private ConfigurationMessage fromProto(PoloProto.Configuration protoMessage) {
        EncodingOption enc = fromProto(protoMessage.encoding);
        OptionsMessage.ProtocolRole role = OptionsMessage.ProtocolRole.UNKNOWN;

        switch (protoMessage.clientRole) {
            case PoloProto.Options.ROLE_TYPE_INPUT:
                role = OptionsMessage.ProtocolRole.INPUT_DEVICE;
                break;
            case PoloProto.Options.ROLE_TYPE_OUTPUT:
                role = OptionsMessage.ProtocolRole.DISPLAY_DEVICE;
                break;
        }

        return new ConfigurationMessage(enc, role);
    }

    /**
     * Converts a {@link PoloProto.ConfigurationAck} to a
     * {@link ConfigurationAckMessage}.
     */
    private ConfigurationAckMessage fromProto(PoloProto.ConfigurationAck protoMessage) {
        return new ConfigurationAckMessage();
    }

    /**
     * Converts a {@link PoloProto.Secret} to a {@link SecretMessage}.
     */
    private SecretMessage fromProto(PoloProto.Secret protoMessage) {
        return new SecretMessage(protoMessage.secret);
    }

    /**
     * Converts a {@link PoloProto.SecretAck} to a {@link SecretAckMessage}.
     */
    private SecretAckMessage fromProto(PoloProto.SecretAck protoMessage) {
        return new SecretAckMessage(protoMessage.secret);
    }

    /**
     * Converts a {@link PoloProto.Options.Encoding} to a {@link EncodingOption}.
     */
    private EncodingOption fromProto(PoloProto.Options.Encoding enc) {
        EncodingOption.EncodingType type;

        switch (enc.type) {
            case PoloProto.Options.Encoding.ENCODING_TYPE_ALPHANUMERIC:
                type = EncodingOption.EncodingType.ENCODING_ALPHANUMERIC;
                break;
            case PoloProto.Options.Encoding.ENCODING_TYPE_HEXADECIMAL:
                type = EncodingOption.EncodingType.ENCODING_HEXADECIMAL;
                break;
            case PoloProto.Options.Encoding.ENCODING_TYPE_NUMERIC:
                type = EncodingOption.EncodingType.ENCODING_NUMERIC;
                break;
            case PoloProto.Options.Encoding.ENCODING_TYPE_QRCODE:
                type = EncodingOption.EncodingType.ENCODING_QRCODE;
                break;
            default:
                type = EncodingOption.EncodingType.ENCODING_UNKNOWN;
        }

        return new EncodingOption(type, enc.symbolLength);

    }

}
