// Copyright (c) 2012 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 <errno.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>

#include <string>
#include <vector>

#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include "shill/error.h"
#include "shill/logging.h"

using base::Callback;
using base::StringPrintf;
using std::string;
using std::vector;

namespace shill {

static gboolean DispatchIOHandler(GIOChannel *chan,
                                  GIOCondition cond,
                                  gpointer data) {
  GlibIOInputHandler *handler = reinterpret_cast<GlibIOInputHandler *>(data);
  unsigned char buf[4096];
  gsize len = 0;
  gint fd = g_io_channel_unix_get_fd(chan);
  GError *err = 0;
  vector<string> error_conditions;

  if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
    string condition = base::StringPrintf(
        "Unexpected GLib error condition %#x on poll(%d): %s",
        cond, fd, strerror(errno));
    LOG(WARNING) << condition;
    error_conditions.push_back(condition);
  }

  GIOStatus status = g_io_channel_read_chars(
      chan, reinterpret_cast<gchar *>(buf), sizeof(buf), &len, &err);
  if (err) {
    string condition = base::StringPrintf(
        "GLib error code %d/%d (%s) on read(%d): %s",
        err->domain, err->code, err->message, fd, strerror(errno));
    LOG(WARNING) << condition;
    error_conditions.push_back(condition);
    g_error_free(err);
  }
  if (status == G_IO_STATUS_AGAIN)
    return TRUE;
  if (status == G_IO_STATUS_ERROR) {
    string condition = base::StringPrintf(
        "Unexpected GLib return status: %d", status);
    LOG(ERROR) << condition;
    error_conditions.push_back(condition);
    Error error(Error::kOperationFailed, JoinString(error_conditions, ';'));
    handler->error_callback().Run(error);
    return FALSE;
  }

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

  if (status == G_IO_STATUS_EOF) {
    LOG(INFO) << "InputHandler on fd " << fd << " closing due to EOF.";
    CHECK_EQ(0U, len);
    return FALSE;
  }
  return TRUE;
}

GlibIOInputHandler::GlibIOInputHandler(
    int fd,
    const InputCallback &input_callback,
    const ErrorCallback &error_callback)
    : channel_(g_io_channel_unix_new(fd)),
      input_callback_(input_callback),
      error_callback_(error_callback),
      source_id_(G_MAXUINT) {
  // To avoid blocking in g_io_channel_read_chars() due to its internal buffer,
  // set the channel to unbuffered, which in turns requires encoding to be NULL.
  // This assumes raw binary data are read from |fd| via the channel.
  CHECK_EQ(G_IO_STATUS_NORMAL, g_io_channel_set_encoding(channel_, NULL, NULL));
  g_io_channel_set_buffered(channel_, FALSE);
  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
