// 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/check.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_
