// Copyright (c) 2011 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.

#include "shill/glib_io_input_handler.h"

#include <stdio.h>
#include <glib.h>

using base::Callback;

namespace shill {

static gboolean DispatchIOHandler(GIOChannel *chan,
                                  GIOCondition cond,
                                  gpointer data) {
  GlibIOInputHandler *handler = reinterpret_cast<GlibIOInputHandler *>(data);
  unsigned char buf[4096];
  gsize len;
  GIOError err;
  gboolean ret = TRUE;

  if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
    return FALSE;

  err = g_io_channel_read(chan, reinterpret_cast<gchar *>(buf), sizeof(buf),
                          &len);
  if (err) {
    if (err == G_IO_ERROR_AGAIN)
      return TRUE;
    len = 0;
    ret = FALSE;
  }

  InputData input_data(buf, len);
  handler->callback().Run(&input_data);

  return ret;
}

GlibIOInputHandler::GlibIOInputHandler(
    int fd, const Callback<void(InputData *)> &callback)
    : channel_(g_io_channel_unix_new(fd)),
      callback_(callback),
      source_id_(G_MAXUINT) {
  g_io_channel_set_close_on_unref(channel_, TRUE);
}

GlibIOInputHandler::~GlibIOInputHandler() {
  g_source_remove(source_id_);
  g_io_channel_shutdown(channel_, TRUE, NULL);
  g_io_channel_unref(channel_);
}

void GlibIOInputHandler::Start() {
  if (source_id_ == G_MAXUINT) {
    source_id_ = g_io_add_watch(channel_,
                                static_cast<GIOCondition>(
                                    G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR),
                                DispatchIOHandler, this);
  }
}

void GlibIOInputHandler::Stop() {
  if (source_id_ != G_MAXUINT) {
    g_source_remove(source_id_);
    source_id_ = G_MAXUINT;
  }
}

}  // namespace shill
