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

#ifndef P2P_COMMON_STRUCT_SERIALIZER_H__
#define P2P_COMMON_STRUCT_SERIALIZER_H__

#include <glib.h>
#include <unistd.h>

#include <base/logging.h>

namespace p2p {

namespace util {

// StructSerializerWrite writes the passed struct T |data| to a file descriptor
// that should be consumed by a StructSerializerWatcher in the other end.
template<typename T>
bool StructSerializerWrite(int fd, const T& data) {
  const char* p = reinterpret_cast<const char*>(&data);
  size_t to_write = sizeof(T);
  int res;

  do {
    res = write(fd, p, to_write);
    if (res < 0 && errno == EAGAIN)
      continue;
    if (res <= 0) {
      PLOG(ERROR) << "Error writing to fd " << fd;
      return false;
    }
    to_write -= res;
    p += res;
  } while (to_write > 0);
  return true;
}

// StructSerializerWarcher adds a new watch to the glib's main loop that reads
// "typename T" objects and fires the provided callback each time such object
// is received. "typename T" is required to have a fixed size and the memory
// representing it is copied from StructSerializerWrite to
// StructSerializerWatcher without any conversion, thus only suitable for
// structs of basic types and fixed length arrays of those.
template<typename T>
class StructSerializerWatcher {
 public:
  // The callback function type that will be used for a StructSerializerWatcher
  // of the struct T.
  typedef void StructSerializerCallback(const T& data, void* user_data);

  StructSerializerWatcher(
      int fd,
      StructSerializerCallback* callback,
      void* user_data)
      : source_id_(0),
      fd_(fd),
      callback_(callback),
      user_data_(user_data),
      buffer_len_(0) {
    GError* error = NULL;

    GIOChannel* io_channel = g_io_channel_unix_new(fd);
    if (g_io_channel_set_encoding(io_channel, NULL, &error) ==
        G_IO_STATUS_ERROR) {
      LOG(ERROR) << "Setting NULL encoding: " << error->message;
      g_error_free(error);
    }
    g_io_channel_set_buffered(io_channel, FALSE);
    source_id_ = g_io_add_watch(
        io_channel,
        static_cast<GIOCondition>(G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP),
        OnIOChannelActivity,
        this);
    g_io_channel_unref(io_channel);
  }

  ~StructSerializerWatcher() {
    if (source_id_)
      g_source_remove(source_id_);
  }

 private:
  static gboolean OnIOChannelActivity(GIOChannel* source,
                                      GIOCondition condition,
                                      gpointer user_data) {
    StructSerializerWatcher<T>* watcher =
        reinterpret_cast<StructSerializerWatcher<T>*>(user_data);
    int bytes_read = 0;

    CHECK(watcher->buffer_len_ < watcher->struct_size_);
    char* char_buffer = reinterpret_cast<char*>(&watcher->buffer_);

    do {
      bytes_read = read(watcher->fd_,
                        char_buffer + watcher->buffer_len_,
                        struct_size_ - watcher->buffer_len_);
    } while (bytes_read < 0 && errno == EAGAIN);
    if (bytes_read < 0) {
      PLOG(ERROR) << "Error reading from pipe";
      return TRUE;
    }

    if ((condition & G_IO_HUP) != 0 || bytes_read == 0) {
      watcher->source_id_ = 0;
      return FALSE;  // Stop monitoring the file.
    }

    watcher->buffer_len_ += bytes_read;
    if (watcher->buffer_len_ == watcher->struct_size_) {
      (*watcher->callback_)(watcher->buffer_, watcher->user_data_);
      watcher->buffer_len_ = 0;
    }

    return TRUE;  // Keep source around.
  }

  // The source id used to track the callback source on the main loop.
  guint source_id_;

  // The passed file descriptor.
  int fd_;

  StructSerializerCallback* callback_;

  // A user provided pointer passed back to callback on every call.
  void* user_data_;

  static const size_t struct_size_ = sizeof(T);

  // The buffer to store partial reads from the passed |fd_|.
  T buffer_;

  // The current number of bytes stored in |buffer_|.
  size_t buffer_len_;
};

}  // namespace util

}  // namespace p2p

#endif  // P2P_COMMON_STRUCT_SERIALIZER_H__
