// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "ipc/named_event.h"

#ifdef OS_WIN
#include <Windows.h>
#include <Sddl.h>
#else
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <semaphore.h>
#include <string.h>
#include <sys/types.h>
#endif

#include <algorithm>
#include <cstdio>
#include <string>

#include "base/const.h"
#include "base/logging.h"
#include "base/port.h"
#include "base/system_util.h"
#include "base/util.h"
#ifdef OS_WIN
#include "base/win_sandbox.h"
#endif  // OS_WIN

namespace mozc {
namespace {

#ifndef OS_WIN
const pid_t kInvalidPid = 1;  // We can safely use 1 as 1 is reserved for init.

// Returns true if the process is alive.
bool IsProcessAlive(pid_t pid) {
  if (pid == kInvalidPid) {
    return true;  // return dummy value.
  }
  const int kSig = 0;
  // As the signal number is 0, no signal is sent, but error checking is
  // still performed.
  return ::kill(pid, kSig) == 0;
}
#endif  // !OS_WIN
}  // namespace

const string NamedEventUtil::GetEventPath(const char *name) {
  name = (name == NULL) ? "NULL" : name;
  string event_name = kEventPathPrefix;
  event_name += SystemUtil::GetUserSidAsString();
  event_name += ".";
  event_name += name;
#ifdef OS_WIN
  return event_name;
#else
  // To maximze mozc portability, (especailly on BSD including OSX),
  // makes the length of path name shorter than 14byte.
  // Please see the following man page for detail:
  // http://www.freebsd.org/cgi/man.cgi?query=sem_open&manpath=FreeBSD+7.0-RELEASE
  // "This implementation places strict requirements on the value of name: it
  //  must begin with a slash (`/'), contain no other slash characters, and be
  //  less than 14 characters in length not including the terminating null
  //  character."
  const size_t kEventPathLength = 14;
  char buf[32];
  snprintf(buf, kEventPathLength, "/%llx", Util::Fingerprint(event_name));
  return buf;
#endif
}

#ifdef OS_WIN
NamedEventListener::NamedEventListener(const char *name)
    : is_owner_(false), handle_(NULL) {
  wstring event_path;
  Util::UTF8ToWide(NamedEventUtil::GetEventPath(name).c_str(), &event_path);

  handle_ = ::OpenEventW(EVENT_ALL_ACCESS, false,
                         event_path.c_str());

  if (handle_ == NULL) {
    SECURITY_ATTRIBUTES security_attributes;
    if (!WinSandbox::MakeSecurityAttributes(WinSandbox::kSharableEvent,
                                            &security_attributes)) {
      LOG(ERROR) << "Cannot make SecurityAttributes";
      return;
    }

    handle_ = ::CreateEventW(&security_attributes,
                             true, false,
                             event_path.c_str());
    ::LocalFree(security_attributes.lpSecurityDescriptor);
    if (handle_ == NULL) {
      LOG(ERROR) << "CreateEvent() failed: " << ::GetLastError();
      return;
    }

    is_owner_ = true;
  }

  VLOG(1) << "NamedEventListener " << name << " is created";
}

NamedEventListener::~NamedEventListener() {
  if (NULL != handle_) {
    ::CloseHandle(handle_);
  }
  handle_ = NULL;
}

bool NamedEventListener::IsAvailable() const {
  return (handle_ != NULL);
}

bool NamedEventListener::IsOwner() const {
  return (IsAvailable() && is_owner_);
}

bool NamedEventListener::Wait(int msec) {
  if (!IsAvailable()) {
    LOG(ERROR) << "NamedEventListener is not available";
    return false;
  }

  if (msec < 0) {
    msec = INFINITE;
  }

  const DWORD result = ::WaitForSingleObject(handle_, msec);
  if (result == WAIT_TIMEOUT) {
    LOG(WARNING) << "NamedEvent timeout " << ::GetLastError();
    return false;
  }

  return true;
}

int NamedEventListener::WaitEventOrProcess(int msec, size_t pid) {
  if (!IsAvailable()) {
    return TIMEOUT;
  }

  HANDLE handle = ::OpenProcess(SYNCHRONIZE,
                                FALSE, static_cast<DWORD>(pid));
  if (NULL == handle) {
    LOG(ERROR) << "OpenProcess: failed() " << ::GetLastError() << " " << pid;
    if (::GetLastError() == ERROR_INVALID_PARAMETER) {
      LOG(ERROR) << "No such process found: " << pid;
      return PROCESS_SIGNALED;
    }
  }

  if (msec < 0) {
    msec = INFINITE;
  }

  HANDLE handles[2] = { handle_, handle };

  const DWORD handles_size = (handle == NULL) ? 1 : 2;

  const DWORD ret = ::WaitForMultipleObjects(handles_size,
                                             handles,
                                             FALSE,
                                             msec);
  int result = TIMEOUT;
  switch (ret) {
    case WAIT_OBJECT_0:
    case WAIT_ABANDONED_0:
      result = EVENT_SIGNALED;
      break;
    case WAIT_OBJECT_0 + 1:
    case WAIT_ABANDONED_0 + 1:
      result = PROCESS_SIGNALED;
      break;
    case WAIT_TIMEOUT:
      LOG(WARNING) << "NamedEvent timeout " << ::GetLastError();
      result = TIMEOUT;
      break;
    default:
      result = TIMEOUT;
      break;
  }

  if (NULL != handle) {
    ::CloseHandle(handle);
  }

  return result;
}

NamedEventNotifier::NamedEventNotifier(const char *name)
    : handle_(NULL) {
  wstring event_path;
  Util::UTF8ToWide(NamedEventUtil::GetEventPath(name).c_str(), &event_path);
  handle_ = ::OpenEventW(EVENT_MODIFY_STATE, false,
                         event_path.c_str());
  if (handle_ == NULL) {
    LOG(ERROR) << "Cannot open Event name: " << name;
    return;
  }
}

NamedEventNotifier::~NamedEventNotifier() {
  if (NULL != handle_) {
    ::CloseHandle(handle_);
  }
  handle_ = NULL;
}

bool NamedEventNotifier::IsAvailable() const {
  return handle_ != NULL;
}

bool NamedEventNotifier::Notify() {
  if (!IsAvailable()) {
    LOG(ERROR) << "NamedEventListener is not available";
    return false;
  }

  if (0 == ::SetEvent(handle_)) {
    LOG(ERROR) << "SetEvent() failed: " << ::GetLastError();
    return false;
  }

  return true;
}

#else   // OS_WIN

NamedEventListener::NamedEventListener(const char *name)
    : is_owner_(false), sem_(SEM_FAILED) {
  key_filename_ = NamedEventUtil::GetEventPath(name);

  sem_ = ::sem_open(key_filename_.c_str(), O_CREAT | O_EXCL, 0600, 0);

  if (sem_ == SEM_FAILED && errno == EEXIST) {
    sem_ = ::sem_open(key_filename_.c_str(), O_CREAT, 0600, 0);
  } else {
    is_owner_ = true;
  }

  if (sem_ == SEM_FAILED) {
    LOG(ERROR) << "sem_open() failed "
               << key_filename_ << " " << ::strerror(errno);
    return;
  }

  VLOG(1) << "NamedEventNotifier " << name << " is created";
}

NamedEventListener::~NamedEventListener() {
  if (IsAvailable()) {
    ::sem_close(sem_);
    ::sem_unlink(key_filename_.c_str());
  }
  sem_ = SEM_FAILED;
}

bool NamedEventListener::IsAvailable() const {
  return sem_ != SEM_FAILED;
}

bool NamedEventListener::IsOwner() const {
  return (IsAvailable() && is_owner_);
}

bool NamedEventListener::Wait(int msec) {
  return WaitEventOrProcess(msec, kInvalidPid /* don't check pid */) ==
      NamedEventListener::EVENT_SIGNALED;
}

int NamedEventListener::WaitEventOrProcess(int msec, size_t pid) {
  if (!IsAvailable()) {
    return NamedEventListener::TIMEOUT;
  }

  const bool inifinite = msec < 0 ? true : false;
  const int kWaitMsec = 200;

  while (inifinite || msec > 0) {
    Util::Sleep(kWaitMsec);

    if (!IsProcessAlive(pid)) {
      return NamedEventListener::PROCESS_SIGNALED;
    }

    if (-1 == ::sem_trywait(sem_)) {
      if (errno != EAGAIN) {
        LOG(ERROR) << "sem_trywait failed: " << ::strerror(errno);
        return EVENT_SIGNALED;
      }
    } else {
      // raise other events recursively.
      if (-1 == ::sem_post(sem_)) {
        LOG(ERROR) << "sem_post failed: " << ::strerror(errno);
      }
      return EVENT_SIGNALED;
    }

    msec -= kWaitMsec;
  }

  // timeout.
  return NamedEventListener::TIMEOUT;
}

NamedEventNotifier::NamedEventNotifier(const char *name)
    : sem_(SEM_FAILED) {
  const string key_filename = NamedEventUtil::GetEventPath(name);
  sem_ = ::sem_open(key_filename.c_str(), 0);
  if (sem_ == SEM_FAILED) {
    LOG(ERROR) << "sem_open failed: " << ::strerror(errno);
  }
}

NamedEventNotifier::~NamedEventNotifier() {
  if (IsAvailable()) {
    ::sem_close(sem_);
  }
  sem_ = SEM_FAILED;
}

bool NamedEventNotifier::IsAvailable() const {
  return sem_ != SEM_FAILED;
}

bool NamedEventNotifier::Notify() {
  if (!IsAvailable()) {
    LOG(ERROR) << "NamedEventNotifier is not available";
    return false;
  }

  if (-1 == ::sem_post(sem_)) {
    LOG(ERROR) << "semop failed: " << ::strerror(errno);
    return false;
  }

  return true;
}
#endif
}  // namespace mozc
