// 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 "cryptohome/cryptohome_event_source.h"

#include <poll.h>
#include <unistd.h>

#include <memory>
#include <utility>

#include <base/logging.h>

namespace cryptohome {

GSourceFuncs CryptohomeEventSource::source_functions_ = {
  CryptohomeEventSource::Prepare,
  CryptohomeEventSource::Check,
  CryptohomeEventSource::Dispatch,
  nullptr
};

CryptohomeEventSource::CryptohomeEventSource() {
  pipe_fds_[0] = -1;
  pipe_fds_[1] = -1;
}

CryptohomeEventSource::~CryptohomeEventSource() {
  Clear();
}

void CryptohomeEventSource::Reset(CryptohomeEventSourceSink* sink,
                                  GMainContext* main_context) {
  sink_ = sink;
  source_.reset();

  for (int i = 0; i < 2; i++) {
    if (pipe_fds_[i] != -1) {
      close(pipe_fds_[i]);
      pipe_fds_[i] = -1;
    }
  }

  Clear();

  if (!pipe(pipe_fds_)) {
    source_.reset(
        static_cast<Source*>(g_source_new(&source_functions_, sizeof(Source))));
    source_->event_source = this;
    source_->poll_fd.fd = pipe_fds_[0];
    source_->poll_fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
    source_->poll_fd.revents = 0;
    g_source_add_poll(source_.get(), &source_->poll_fd);
    if (main_context) {
      g_source_attach(source_.get(), main_context);
    }
    g_source_set_can_recurse(source_.get(), true);
  } else {
    LOG(ERROR) << "Couldn't set up pipe for notifications.";
  }
}

bool CryptohomeEventSource::EventsPending() {
  bool result = true;
  if (events_lock_.Try()) {
    result = !events_.empty();
    events_lock_.Release();
  }
  return result;
}

void CryptohomeEventSource::HandleDispatch() {
  // Clear pending notifications from the pipe.  This is done in reverse order
  // of the AddEvent() function so that we cannot get into a state where there
  // is an event queued but no pending read on the pipe.
  bool more = false;
  do {
    struct pollfd fds = { pipe_fds_[0], POLLIN, 0 };
    if (poll(&fds, 1, 0) && (fds.revents & POLLIN)) {
      char c;
      if (read(pipe_fds_[0], &c, 1) == 1) {
        more = true;
      } else {
        more = false;
      }
    } else {
      more = false;
    }
  } while (more);

  // Now handle pending events.
  std::vector<std::unique_ptr<CryptohomeEventBase>> events;
  {
    base::AutoLock lock(events_lock_);
    events_.swap(events);
  }

  for (auto& event : events) {
    if (sink_) {
      sink_->NotifyEvent(event.get());
    }
  }
}

void CryptohomeEventSource::AddEvent(
    std::unique_ptr<CryptohomeEventBase> event) {
  base::AutoLock lock(events_lock_);
  events_.push_back(std::move(event));
  if (write(pipe_fds_[1], "G", 1) != 1) {
    LOG(INFO) << "Couldn't notify of pending events through the message pipe."
              << "  Events will be cleared on next call to Prepare().";
  }
}

void CryptohomeEventSource::Clear() {
  base::AutoLock lock(events_lock_);
  events_.clear();
}

void CryptohomeEventSource::SourceDeleter::operator()(Source* source) {
  g_source_destroy(source);
  g_source_unref(source);
}

gboolean CryptohomeEventSource::Prepare(GSource* source, gint* timeout_ms) {
  if (static_cast<Source*>(source)->event_source->EventsPending()) {
    *timeout_ms = 0;
    return true;
  }
  *timeout_ms = -1;
  return false;
}

gboolean CryptohomeEventSource::Check(GSource* source) {
  return static_cast<Source*>(source)->event_source->EventsPending();
}

gboolean CryptohomeEventSource::Dispatch(GSource* source,
                                         GSourceFunc unused_func,
                                         gpointer unused_data) {
  static_cast<Source*>(source)->event_source->HandleDispatch();
  return true;
}

}  // namespace cryptohome
