// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/pairing/proto_decoder.h"

#include "components/pairing/pairing_api.pb.h"
#include "net/base/io_buffer.h"

namespace {
enum {
  MESSAGE_NONE,
  MESSAGE_HOST_STATUS,
  MESSAGE_CONFIGURE_HOST,
  MESSAGE_PAIR_DEVICES,
  MESSAGE_COMPLETE_SETUP,
  MESSAGE_ERROR,
  NUM_MESSAGES,
};
}

namespace pairing_chromeos {

ProtoDecoder::ProtoDecoder(Observer* observer)
    : observer_(observer),
      next_message_type_(MESSAGE_NONE),
      next_message_size_(0) {
  DCHECK(observer_);
}

ProtoDecoder::~ProtoDecoder() {}

bool ProtoDecoder::DecodeIOBuffer(int size,
                                  ProtoDecoder::IOBufferRefPtr io_buffer) {
  // Update the message buffer.
  message_buffer_.AddIOBuffer(io_buffer, size);

  // If there is no current message, the next byte is the message type.
  if (next_message_type_ == MESSAGE_NONE) {
    if (message_buffer_.AvailableBytes() < static_cast<int>(sizeof(uint8_t)))
      return true;

    uint8_t message_type = MESSAGE_NONE;
    message_buffer_.ReadBytes(reinterpret_cast<char*>(&message_type),
                               sizeof(message_type));

    if (message_type == MESSAGE_NONE || message_type >= NUM_MESSAGES) {
      LOG(ERROR) << "Unknown message type received: " << message_type;
      return false;
    }
    next_message_type_ = message_type;
  }

  // If the message size isn't set, the next two bytes are the message size.
  if (next_message_size_ == 0) {
    if (message_buffer_.AvailableBytes() < static_cast<int>(sizeof(uint16_t)))
      return true;

    // The size is sent in network byte order.
    uint8_t high_byte = 0;
    message_buffer_.ReadBytes(reinterpret_cast<char*>(&high_byte),
                               sizeof(high_byte));
    uint8_t low_byte = 0;
    message_buffer_.ReadBytes(reinterpret_cast<char*>(&low_byte),
                               sizeof(low_byte));

    next_message_size_ = (high_byte << 8) + low_byte;
  }

  // If the whole proto buffer is not yet available, return early.
  if (message_buffer_.AvailableBytes() < next_message_size_)
    return true;

  std::vector<char> buffer(next_message_size_);
  message_buffer_.ReadBytes(&buffer[0], next_message_size_);

  switch (next_message_type_) {
    case MESSAGE_HOST_STATUS: {
        pairing_api::HostStatus message;
        message.ParseFromArray(&buffer[0], buffer.size());
        observer_->OnHostStatusMessage(message);
      }
      break;
    case MESSAGE_CONFIGURE_HOST: {
        pairing_api::ConfigureHost message;
        message.ParseFromArray(&buffer[0], buffer.size());
        observer_->OnConfigureHostMessage(message);
      }
      break;
    case MESSAGE_PAIR_DEVICES: {
        pairing_api::PairDevices message;
        message.ParseFromArray(&buffer[0], buffer.size());
        observer_->OnPairDevicesMessage(message);
      }
      break;
    case MESSAGE_COMPLETE_SETUP: {
        pairing_api::CompleteSetup message;
        message.ParseFromArray(&buffer[0], buffer.size());
        observer_->OnCompleteSetupMessage(message);
      }
      break;
    case MESSAGE_ERROR: {
        pairing_api::Error message;
        message.ParseFromArray(&buffer[0], buffer.size());
        observer_->OnErrorMessage(message);
      }
      break;

    default:
      NOTREACHED();
      break;
  }

  // Reset the message data.
  next_message_type_ = MESSAGE_NONE;
  next_message_size_ = 0;

  return true;
}

ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendHostStatus(
    const pairing_api::HostStatus& message, int* size) {
  std::string serialized_proto;
  if (!message.SerializeToString(&serialized_proto)) {
    NOTREACHED();
  }

  return SendMessage(MESSAGE_HOST_STATUS, serialized_proto, size);
}

ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendConfigureHost(
    const pairing_api::ConfigureHost& message, int* size) {
  std::string serialized_proto;
  if (!message.SerializeToString(&serialized_proto)) {
    NOTREACHED();
  }

  return SendMessage(MESSAGE_CONFIGURE_HOST, serialized_proto, size);
}

ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendPairDevices(
    const pairing_api::PairDevices& message, int* size) {
  std::string serialized_proto;
  if (!message.SerializeToString(&serialized_proto)) {
    NOTREACHED();
  }

  return SendMessage(MESSAGE_PAIR_DEVICES, serialized_proto, size);
}

ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendCompleteSetup(
    const pairing_api::CompleteSetup& message, int* size) {
  std::string serialized_proto;
  if (!message.SerializeToString(&serialized_proto)) {
    NOTREACHED();
  }

  return SendMessage(MESSAGE_COMPLETE_SETUP, serialized_proto, size);
}

ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendError(
    const pairing_api::Error& message, int* size) {
  std::string serialized_proto;
  if (!message.SerializeToString(&serialized_proto)) {
    NOTREACHED();
  }

  return SendMessage(MESSAGE_ERROR, serialized_proto, size);
}

ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendMessage(
    uint8_t message_type,
    const std::string& message,
    int* size) {
  uint16_t message_size = message.size();

  *size = sizeof(message_type) + sizeof(message_size) + message.size();
  IOBufferRefPtr io_buffer(new net::IOBuffer(*size));

  // Write the message type.
  int offset = 0;
  memcpy(&io_buffer->data()[offset], &message_type, sizeof(message_type));
  offset += sizeof(message_type);

  // Network byte order.
  // Write the high byte of the size.
  uint8_t data = (message_size >> 8) & 0xFF;
  memcpy(&io_buffer->data()[offset], &data, sizeof(data));
  offset += sizeof(data);
  // Write the low byte of the size.
  data = message_size & 0xFF;
  memcpy(&io_buffer->data()[offset], &data, sizeof(data));
  offset += sizeof(data);

  // Write the actual message.
  memcpy(&io_buffer->data()[offset], message.data(), message.size());

  return io_buffer;
}

}  // namespace pairing_chromeos
