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

#include <errno.h>

#ifdef OS_WIN
#include <windows.h>
#include <psapi.h>   // GetModuleFileNameExW
#else
// For stat system call
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef OS_MACOSX
#include <sys/sysctl.h>
#endif  // OS_MACOSX
#endif  // OS_WIN

#include <cstdlib>
#include <map>
#ifdef OS_WIN
#include <memory>  // for std::unique_ptr
#endif

#include "base/const.h"
#include "base/file_stream.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/mac_util.h"
#include "base/mutex.h"
#include "base/port.h"
#include "base/process_mutex.h"
#include "base/scoped_handle.h"
#include "base/singleton.h"
#include "base/system_util.h"
#include "base/util.h"
#include "base/version.h"
#include "base/win_util.h"
#include "ipc/ipc.h"
#include "ipc/ipc.pb.h"

#ifdef OS_WIN
using std::unique_ptr;
#endif  // OS_WIn

namespace mozc {
namespace {

// size of key
const size_t kKeySize = 32;

// Do not use ConfigFileStream, since client won't link
// to the embedded resource files
string GetIPCKeyFileName(const string &name) {
#ifdef OS_WIN
  string basename;
#else
  string basename = ".";    // hidden file
#endif
  basename += name + ".ipc";
  return FileUtil::JoinPath(SystemUtil::GetUserProfileDirectory(), basename);
}

bool IsValidKey(const string &name) {
  if (kKeySize != name.size()) {
    LOG(ERROR) << "IPCKey is invalid length";
    return false;
  }

  for (size_t i = 0; i < name.size(); ++i) {
    if ((name[i] >= '0' && name[i] <= '9') ||
        (name[i] >= 'a' && name[i] <= 'f')) {
      // do nothing
    } else {
      LOG(ERROR) << "key name is invalid: " << name[i];
      return false;
    }
  }

  return true;
}

void CreateIPCKey(char *value) {
  char buf[16];   // key is 128 bit

#ifdef OS_WIN
  // LUID guaranties uniqueness
  LUID luid = { 0 };   // LUID is 64bit value

  DCHECK_EQ(sizeof(luid), sizeof(uint64));

  // first 64 bit is random sequence and last 64 bit is LUID
  if (::AllocateLocallyUniqueId(&luid)) {
    Util::GetRandomSequence(buf, sizeof(buf) / 2);
    ::memcpy(buf + sizeof(buf) / 2, &luid, sizeof(buf) / 2);
  } else {
    // use random value for failsafe
    Util::GetRandomSequence(buf, sizeof(buf));
  }
#else
  // get 128 bit key: Note that collision will happen.
  Util::GetRandomSequence(buf, sizeof(buf));
#endif

  // escape
  for (size_t i = 0; i < sizeof(buf); ++i) {
    const int hi = ((static_cast<int>(buf[i]) & 0xF0) >> 4);
    const int lo = (static_cast<int>(buf[i]) & 0x0F);
    value[2 * i]     = static_cast<char>(hi >= 10 ? hi - 10 + 'a' : hi + '0');
    value[2 * i + 1] = static_cast<char>(lo >= 10 ? lo - 10 + 'a' : lo + '0');
  }

  value[kKeySize] = '\0';
}

class IPCPathManagerMap {
 public:
  IPCPathManager *GetIPCPathManager(const string &name) {
    scoped_lock l(&mutex_);
    map<string, IPCPathManager *>::const_iterator it = manager_map_.find(name);
    if (it != manager_map_.end()) {
      return it->second;
    }
    IPCPathManager *manager = new IPCPathManager(name);
    manager_map_.insert(make_pair(name, manager));
    return manager;
  }

  IPCPathManagerMap() {}

  ~IPCPathManagerMap() {
    scoped_lock l(&mutex_);
    for (map<string, IPCPathManager *>::iterator it = manager_map_.begin();
         it != manager_map_.end(); ++it) {
      delete it->second;
    }
    manager_map_.clear();
  }

 private:
  map<string, IPCPathManager *> manager_map_;
  Mutex mutex_;
};

}  // namespace

IPCPathManager::IPCPathManager(const string &name)
    : mutex_(new Mutex),
      ipc_path_info_(new ipc::IPCPathInfo),
      name_(name),
      server_pid_(0),
      last_modified_(-1) {}

IPCPathManager::~IPCPathManager() {}

IPCPathManager *IPCPathManager::GetIPCPathManager(const string &name) {
  IPCPathManagerMap *manager_map = Singleton<IPCPathManagerMap>::get();
  DCHECK(manager_map != NULL);
  return manager_map->GetIPCPathManager(name);
}

bool IPCPathManager::CreateNewPathName() {
  scoped_lock l(mutex_.get());
  if (ipc_path_info_->key().empty()) {
    char ipc_key[kKeySize + 1];
    CreateIPCKey(ipc_key);
    ipc_path_info_->set_key(ipc_key);
  }
  return true;
}

bool IPCPathManager::SavePathName() {
  scoped_lock l(mutex_.get());
  if (path_mutex_.get() != NULL) {
    return true;
  }

  path_mutex_.reset(new ProcessMutex("ipc"));

  path_mutex_->set_lock_filename(GetIPCKeyFileName(name_));

  // a little tricky as CreateNewPathName() tries mutex lock
  CreateNewPathName();

  // set the server version
  ipc_path_info_->set_protocol_version(IPC_PROTOCOL_VERSION);
  ipc_path_info_->set_product_version(Version::GetMozcVersion());

#ifdef OS_WIN
  ipc_path_info_->set_process_id(static_cast<uint32>(::GetCurrentProcessId()));
  ipc_path_info_->set_thread_id(static_cast<uint32>(::GetCurrentThreadId()));
#else
  ipc_path_info_->set_process_id(static_cast<uint32>(getpid()));
  ipc_path_info_->set_thread_id(0);
#endif

  string buf;
  if (!ipc_path_info_->SerializeToString(&buf)) {
    LOG(ERROR) << "SerializeToString failed";
    return false;
  }

  if (!path_mutex_->LockAndWrite(buf)) {
    LOG(ERROR) << "ipc key file is already locked";
    return false;
  }

  VLOG(1) << "ServerIPCKey: " << ipc_path_info_->key();

  last_modified_ = GetIPCFileTimeStamp();
  return true;
}

bool IPCPathManager::LoadPathName() {
  // On Windows, ShouldReload() always returns false.
  // On other platform, it returns true when timestamp of the file is different
  // from that of previous one.
  if (ShouldReload() || ipc_path_info_->key().empty()) {
    if (!LoadPathNameInternal()) {
      LOG(ERROR) << "LoadPathName failed";
      return false;
    }
  }
  return true;
}

bool IPCPathManager::GetPathName(string *ipc_name) const {
  if (ipc_name == NULL) {
    LOG(ERROR) << "ipc_name is NULL";
    return false;
  }

  if (ipc_path_info_->key().empty()) {
    LOG(ERROR) << "ipc_path_info_ is empty";
    return false;
  }

#ifdef OS_WIN
  *ipc_name = mozc::kIPCPrefix;
#elif defined(OS_MACOSX)
  ipc_name->assign(MacUtil::GetLabelForSuffix(""));
#else  // not OS_WIN nor OS_MACOSX
  // GetUserIPCName("<name>") => "/tmp/.mozc.<key>.<name>"
  const char kIPCPrefix[] = "/tmp/.mozc.";
  *ipc_name = kIPCPrefix;
#endif  // OS_WIN

#ifdef OS_LINUX
  // On Linux, use abstract namespace which is independent of the file system.
  (*ipc_name)[0] = '\0';
#endif

  ipc_name->append(ipc_path_info_->key());
  ipc_name->append(".");
  ipc_name->append(name_);

  return true;
}

uint32 IPCPathManager::GetServerProtocolVersion() const {
  return ipc_path_info_->protocol_version();
}

const string &IPCPathManager::GetServerProductVersion() const {
  return ipc_path_info_->product_version();
}

uint32 IPCPathManager::GetServerProcessId() const {
  return ipc_path_info_->process_id();
}

void IPCPathManager::Clear() {
  scoped_lock l(mutex_.get());
  ipc_path_info_->Clear();
}

bool IPCPathManager::IsValidServer(uint32 pid,
                                   const string &server_path) {
  scoped_lock l(mutex_.get());
  if (pid == 0) {
    // For backward compatibility.
    return true;
  }
  if (server_path.empty()) {
    // This means that we do not check the server path.
    return true;
  }

  if (pid == static_cast<uint32>(-1)) {
    VLOG(1) << "pid is -1. so assume that it is an invalid program";
    return false;
  }

  // compare path name
  if (pid == server_pid_) {
    return (server_path == server_path_);
  }

  server_pid_ = 0;
  server_path_.clear();

#ifdef OS_WIN
  {
    wstring expected_server_ntpath;
    const map<string, wstring>::const_iterator it =
        expected_server_ntpath_cache_.find(server_path);
    if (it != expected_server_ntpath_cache_.end()) {
      expected_server_ntpath = it->second;
    } else {
      wstring wide_server_path;
      Util::UTF8ToWide(server_path, &wide_server_path);
      if (WinUtil::GetNtPath(wide_server_path, &expected_server_ntpath)) {
        // Caches the relationship from |server_path| to
        // |expected_server_ntpath| in case |server_path| is renamed later.
        // (This can happen during the updating).
        expected_server_ntpath_cache_[server_path] = expected_server_ntpath;
      }
    }

    if (expected_server_ntpath.empty()) {
      return false;
    }

    wstring actual_server_ntpath;
    if (!WinUtil::GetProcessInitialNtPath(pid, &actual_server_ntpath)) {
      return false;
    }

    if (expected_server_ntpath != actual_server_ntpath) {
      return false;
    }

    // Here we can safely assume that |server_path| (expected one) should be
    // the same to |server_path_| (actual one).
    server_path_ = server_path;
    server_pid_ = pid;
  }
#endif  // OS_WIN

#ifdef OS_MACOSX
  int name[] = { CTL_KERN, KERN_PROCARGS, pid };
  size_t data_len = 0;
  if (sysctl(name, arraysize(name), NULL,
             &data_len, NULL, 0) < 0) {
    LOG(ERROR) << "sysctl KERN_PROCARGS failed";
    return false;
  }

  server_path_.resize(data_len);
  if (sysctl(name, arraysize(name), &server_path_[0],
             &data_len, NULL, 0) < 0) {
    LOG(ERROR) << "sysctl KERN_PROCARGS failed";
    return false;
  }
  server_pid_ = pid;
#endif  // OS_MACOSX

#ifdef OS_LINUX
  // load from /proc/<pid>/exe
  char proc[128];
  char filename[512];
  snprintf(proc, sizeof(proc) - 1, "/proc/%u/exe", pid);
  const ssize_t size = readlink(proc, filename, sizeof(filename) - 1);
  if (size == -1) {
    LOG(ERROR) << "readlink failed: " << strerror(errno);
    return false;
  }
  filename[size] = '\0';

  server_path_ = filename;
  server_pid_ = pid;
#endif  // OS_LINUX

  VLOG(1) << "server path: " << server_path << " " << server_path_;
  if (server_path == server_path_) {
    return true;
  }

#ifdef OS_LINUX
  if ((server_path + " (deleted)") == server_path_) {
    LOG(WARNING) << server_path << " on disk is modified";
    // If a user updates the server binary on disk during the server is running,
    // "readlink /proc/<pid>/exe" returns a path with the " (deleted)" suffix.
    // We allow the special case.
    server_path_ = server_path;
    return true;
  }
#endif  // OS_LINUX

  return false;
}

bool IPCPathManager::ShouldReload() const {
#ifdef OS_WIN
  // In windows, no reloading mechanism is necessary because IPC files
  // are automatically removed.
  return false;
#else
  scoped_lock l(mutex_.get());

  time_t last_modified = GetIPCFileTimeStamp();
  if (last_modified == last_modified_) {
    return false;
  }

  return true;
#endif  // OS_WIN
}

time_t IPCPathManager::GetIPCFileTimeStamp() const {
#ifdef OS_WIN
  // In windows, we don't need to get the exact file timestamp, so
  // just returns -1 at this time.
  return static_cast<time_t>(-1);
#else
  const string filename = GetIPCKeyFileName(name_);
  struct stat filestat;
  if (::stat(filename.c_str(), &filestat) == -1) {
    VLOG(2) << "stat(2) failed.  Skipping reload";
    return static_cast<time_t>(-1);
  }
  return filestat.st_mtime;
#endif  // OS_WIN
}

bool IPCPathManager::LoadPathNameInternal() {
  scoped_lock l(mutex_.get());

  // try the new file name first.
  const string filename = GetIPCKeyFileName(name_);

  // Special code for Windows,
  // we want to pass FILE_SHRED_DELETE flag for CreateFile.
#ifdef OS_WIN
  wstring wfilename;
  Util::UTF8ToWide(filename.c_str(), &wfilename);

  {
    ScopedHandle handle
        (::CreateFileW(wfilename.c_str(),
                       GENERIC_READ,
                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                       NULL, OPEN_EXISTING, 0, NULL));

    // ScopedHandle does not receive INVALID_HANDLE_VALUE and
    // NULL check is appropriate here.
    if (NULL == handle.get()) {
      LOG(ERROR) << "cannot open: " << filename << " " << ::GetLastError();
      return false;
    }

    const DWORD size = ::GetFileSize(handle.get(), NULL);
    if (-1 == static_cast<int>(size)) {
      LOG(ERROR) << "GetFileSize failed: " << ::GetLastError();
      return false;
    }

    const DWORD kMaxFileSize = 2096;
    if (size == 0 || size >= kMaxFileSize) {
      LOG(ERROR) << "Invalid file size: " << kMaxFileSize;
      return false;
    }

    unique_ptr<char[]> buf(new char[size]);

    DWORD read_size = 0;
    if (!::ReadFile(handle.get(), buf.get(),
                    size, &read_size, NULL)) {
      LOG(ERROR) << "ReadFile failed: " << ::GetLastError();
      return false;
    }

    if (read_size != size) {
      LOG(ERROR) << "read_size != size";
      return false;
    }

    if (!ipc_path_info_->ParseFromArray(buf.get(), static_cast<int>(size))) {
      LOG(ERROR) << "ParseFromStream failed";
      return false;
    }
  }

#else

  InputFileStream is(filename.c_str(), ios::binary|ios::in);
  if (!is) {
    LOG(ERROR) << "cannot open: " << filename;
    return false;
  }

  if (!ipc_path_info_->ParseFromIstream(&is)) {
    LOG(ERROR) << "ParseFromStream failed";
    return false;
  }
#endif

  if (!IsValidKey(ipc_path_info_->key())) {
    LOG(ERROR) << "IPCServer::key is invalid";
    return false;
  }

  VLOG(1) << "ClientIPCKey: " << ipc_path_info_->key();
  VLOG(1) << "ProtocolVersion: " << ipc_path_info_->protocol_version();

  last_modified_ = GetIPCFileTimeStamp();
  return true;
}
}  // namespace mozc
