// Copyright 2010-2014, 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.

// skip all unless OS_WIN
#ifdef OS_WIN

#include "ipc/ipc.h"

#include <Windows.h>
#include <Sddl.h>

#include <string>

#include "base/const.h"
#include "base/cpu_stats.h"
#include "base/logging.h"
#include "base/mutex.h"
#include "base/scoped_handle.h"
#include "base/singleton.h"
#include "base/system_util.h"
#include "base/thread.h"
#include "base/util.h"
#include "base/win_sandbox.h"
#include "base/win_util.h"
#include "ipc/ipc_path_manager.h"

namespace mozc {
namespace {

const bool kReadTypeACK = true;
const bool kReadTypeData = false;
const bool kSendTypeData = false;
const int kMaxSuccessiveConnectionFailureCount = 5;

typedef BOOL (WINAPI *FPGetNamedPipeServerProcessId)(HANDLE, PULONG);
FPGetNamedPipeServerProcessId g_get_named_pipe_server_process_id = nullptr;

typedef BOOL (WINAPI *FPSetFileCompletionNotificationModes)(HANDLE, UCHAR);
FPSetFileCompletionNotificationModes
    g_set_file_completion_notification_modes = nullptr;

// Defined when _WIN32_WINNT >= 0x600
#ifndef FILE_SKIP_SET_EVENT_ON_HANDLE
#define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2
#endif  // FILE_SKIP_SET_EVENT_ON_HANDLE

once_t g_once = MOZC_ONCE_INIT;

void InitAPIsForVistaAndLater() {
  // We have to load the function pointer dynamically
  // as GetNamedPipeServerProcessId() is only available on Windows Vista.
  if (!SystemUtil::IsVistaOrLater()) {
    return;
  }

  VLOG(1) << "Initializing GetNamedPipeServerProcessId";
  // kernel32.dll must be loaded in client.
  const HMODULE lib = WinUtil::GetSystemModuleHandle(L"kernel32.dll");
  if (lib == nullptr) {
    LOG(ERROR) << "GetSystemModuleHandle for kernel32.dll failed.";
    return;
  }

  g_get_named_pipe_server_process_id =
      reinterpret_cast<FPGetNamedPipeServerProcessId>
      (::GetProcAddress(lib, "GetNamedPipeServerProcessId"));

  g_set_file_completion_notification_modes =
      reinterpret_cast<FPSetFileCompletionNotificationModes>
      (::GetProcAddress(lib, "SetFileCompletionNotificationModes"));
}

size_t GetNumberOfProcessors() {
  // thread-safety is not required.
  static size_t num = CPUStats().GetNumberOfProcessors();
  return max(num, 1);
}

// Least significant bit of OVERLAPPED::hEvent can be used for special
// purpose against GetQueuedCompletionStatus API.
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364986.aspx
// This function provides a safe way to retrieve the actual event handle
// even in this situation.
HANDLE GetEventHandleFromOverlapped(const OVERLAPPED *overlapped) {
  return reinterpret_cast<HANDLE>(
      reinterpret_cast<DWORD_PTR>(overlapped->hEvent) & ~1);
}

// Returns true if the given |overlapped| is initialized in successful.
bool InitOverlapped(OVERLAPPED *overlapped, HANDLE wait_handle) {
  if (wait_handle == 0 || wait_handle == INVALID_HANDLE_VALUE) {
    LOG(ERROR) << "wait_handle is invalid.";
    return false;
  }
  ::ZeroMemory(overlapped, sizeof(OVERLAPPED));
  if (::ResetEvent(wait_handle) == FALSE) {
    const DWORD last_error = ::GetLastError();
    LOG(ERROR) << "::ResetEvent failed. error: " << last_error;
    return false;
  }
  overlapped->hEvent = wait_handle;
  return true;
}

class IPCClientMutexBase {
 public:
  explicit IPCClientMutexBase(const string &ipc_channel_name) {
    // Make a kernel mutex object so that multiple ipc connections are
    // serialized here. In Windows, there is no useful way to serialize
    // the multiple connections to the single-thread named pipe server.
    // WaitForNamedPipe doesn't work for this propose as it just lets
    // clients know that the connection becomes "available" right now.
    // It doesn't mean that connection is available for the current
    // thread. The "available" notification is sent to all waiting ipc
    // clients at the same time and only one client gets the connection.
    // This causes redundant and wasteful CreateFile calles.
    string mutex_name = kMutexPathPrefix;
    mutex_name += SystemUtil::GetUserSidAsString();
    mutex_name += ".";
    mutex_name += ipc_channel_name;
    mutex_name += ".ipc";
    wstring wmutex_name;
    Util::UTF8ToWide(mutex_name.c_str(), &wmutex_name);

    LPSECURITY_ATTRIBUTES security_attributes_ptr = nullptr;
    SECURITY_ATTRIBUTES security_attributes;
    if (!WinSandbox::MakeSecurityAttributes(WinSandbox::kSharableMutex,
                                            &security_attributes)) {
      LOG(ERROR) << "Cannot make SecurityAttributes";
    } else {
      security_attributes_ptr = &security_attributes;
    }

    // http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx:
    // Two or more processes can call CreateMutex to create the same named
    // mutex. The first process actually creates the mutex, and subsequent
    // processes with sufficient access rights simply open a handle to
    // the existing mutex. This enables multiple processes to get handles
    // of the same mutex, while relieving the user of the responsibility
    // of ensuring that the creating process is started first.
    // When using this technique, you should set the
    // bInitialOwner flag to FALSE; otherwise, it can be difficult to be
    // certain which process has initial ownership.
    ipc_mutex_.reset(::CreateMutex(security_attributes_ptr,
                                   FALSE, wmutex_name.c_str()));
    if (security_attributes_ptr != nullptr) {
      ::LocalFree(security_attributes_ptr->lpSecurityDescriptor);
    }

    const DWORD create_mutex_error = ::GetLastError();
    if (ipc_mutex_.get() == nullptr) {
      LOG(ERROR) << "CreateMutex failed: " << create_mutex_error;
      return;
    }
  }

  virtual ~IPCClientMutexBase() {}

  HANDLE get() const {
    return ipc_mutex_.get();
  }

 private:
  ScopedHandle ipc_mutex_;
};

class ConverterClientMutex : public IPCClientMutexBase {
 public:
  ConverterClientMutex()
      : IPCClientMutexBase("converter") {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ConverterClientMutex);
};

class RendererClientMutex : public IPCClientMutexBase {
 public:
  RendererClientMutex()
      : IPCClientMutexBase("renderer") {}

 private:
  DISALLOW_COPY_AND_ASSIGN(RendererClientMutex);
};

class FallbackClientMutex : public IPCClientMutexBase {
 public:
  FallbackClientMutex()
      : IPCClientMutexBase("fallback") {}

 private:
  DISALLOW_COPY_AND_ASSIGN(FallbackClientMutex);
};

// In Mozc client, we should support different IPC channels (client-converter
// and client-renderer) so we need to have different global mutexes to
// serialize each client. Currently |ipc_name| starts with "session" and
// "renderer" are expected.
HANDLE GetClientMutex(const string &ipc_name) {
  if (Util::StartsWith(ipc_name, "session")) {
    return Singleton<ConverterClientMutex>::get()->get();
  }
  if (Util::StartsWith(ipc_name, "renderer")) {
    return Singleton<RendererClientMutex>::get()->get();
  }
  LOG(WARNING) << "unexpected IPC name: " << ipc_name;
  return Singleton<FallbackClientMutex>::get()->get();
}

// RAII class for calling ReleaseMutex in destructor.
class ScopedReleaseMutex {
 public:
  explicit ScopedReleaseMutex(HANDLE handle)
      : pipe_handle_(handle) {}

  virtual ~ScopedReleaseMutex() {
    if (nullptr != pipe_handle_) {
      ::ReleaseMutex(pipe_handle_);
    }
    pipe_handle_ = nullptr;
  }

  HANDLE get() const {
    return pipe_handle_;
  }

 private:
  HANDLE pipe_handle_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedReleaseMutex);
};

uint32 GetServerProcessIdImpl(HANDLE handle) {
  CallOnce(&g_once, &InitAPIsForVistaAndLater);

  if (g_get_named_pipe_server_process_id == nullptr) {
    return static_cast<uint32>(0);   // must be Windows XP
  }

  ULONG pid = 0;
  if ((*g_get_named_pipe_server_process_id)(handle, &pid) == 0) {
    const DWORD get_named_pipe_server_process_id_error = ::GetLastError();
    LOG(ERROR) << "GetNamedPipeServerProcessId failed: "
               << get_named_pipe_server_process_id_error;
    return static_cast<uint32>(-1);   // always deny the connection
  }

  VLOG(1) << "Got server ProcessID: " << pid;

  return static_cast<uint32>(pid);
}

void SafeCancelIO(HANDLE device_handle, OVERLAPPED *overlapped) {
  if (::CancelIo(device_handle) == FALSE) {
    const DWORD cancel_error = ::GetLastError();
    LOG(ERROR) << "Failed to CancelIo: " << cancel_error;
  }

  // Wait for the completion of the on-going request forever. This is not
  // _safe_ and should be fixed anyway.
  // TODO(yukawa): Avoid INFINITE if possible.
  ::WaitForSingleObject(GetEventHandleFromOverlapped(overlapped), INFINITE);
}

bool WaitForQuitOrIOImpl(
    HANDLE device_handle, HANDLE quit_event, DWORD timeout,
    OVERLAPPED *overlapped, IPCErrorType *last_ipc_error) {
  const HANDLE events[] = {
    quit_event, GetEventHandleFromOverlapped(overlapped)
  };
  const DWORD wait_result = ::WaitForMultipleObjects(
      ARRAYSIZE(events), events, FALSE, timeout);
  const DWORD wait_error = ::GetLastError();
  // Clear the I/O operation if still exists.
  if (!HasOverlappedIoCompleted(overlapped)) {
    // This is not safe because this operation may be blocked forever.
    // TODO(yukawa): Implement safer cancelation mechanism.
    SafeCancelIO(device_handle, overlapped);
  }
  if (wait_result == WAIT_TIMEOUT) {
    LOG(WARNING) << "Timeout: " << timeout;
    *last_ipc_error = IPC_TIMEOUT_ERROR;
    return false;
  }
  if (wait_result == WAIT_OBJECT_0) {
    // Should be quit immediately
    *last_ipc_error = IPC_QUIT_EVENT_SIGNALED;
    return false;
  }
  if (wait_result != (WAIT_OBJECT_0 + 1)) {
    LOG(WARNING) << "Unknown result: " << wait_result
                 << ", Error: " << wait_error;
    *last_ipc_error = IPC_UNKNOWN_ERROR;
    return false;
  }
  return true;
}

bool WaitForIOImpl(HANDLE device_handle, DWORD timeout,
                   OVERLAPPED *overlapped, IPCErrorType *last_ipc_error) {
  const DWORD wait_result = ::WaitForSingleObject(
      GetEventHandleFromOverlapped(overlapped), timeout);
  // Clear the I/O operation if still exists.
  if (!HasOverlappedIoCompleted(overlapped)) {
    // This is not safe because this operation may be blocked forever.
    // TODO(yukawa): Implement safer cancelation mechanism.
    SafeCancelIO(device_handle, overlapped);
  }
  if (wait_result == WAIT_TIMEOUT) {
    LOG(WARNING) << "Timeout: " << timeout;
    *last_ipc_error = IPC_TIMEOUT_ERROR;
    return false;
  }
  if (wait_result != WAIT_OBJECT_0) {
    LOG(WARNING) << "Unknown result: " << wait_result;
    *last_ipc_error = IPC_UNKNOWN_ERROR;
    return false;
  }
  return true;
}

bool WaitForQuitOrIO(
    HANDLE device_handle, HANDLE quit_event, DWORD timeout,
    OVERLAPPED *overlapped, IPCErrorType *last_ipc_error) {
  if (quit_event != nullptr) {
    return WaitForQuitOrIOImpl(device_handle, quit_event, timeout,
                               overlapped, last_ipc_error);
  }
  return WaitForIOImpl(device_handle, timeout, overlapped, last_ipc_error);
}

// To work around a bug of GetOverlappedResult in Vista
// http://msdn.microsoft.com/en-us/library/dd371711.aspx
bool SafeWaitOverlappedResult(
    HANDLE device_handle, HANDLE quit_event, DWORD timeout,
    OVERLAPPED *overlapped, DWORD *num_bytes_updated,
    IPCErrorType *last_ipc_error, bool wait_ack) {
  DCHECK(overlapped);
  DCHECK(num_bytes_updated);
  DCHECK(last_ipc_error);
  if (!WaitForQuitOrIO(device_handle, quit_event, timeout,
                       overlapped, last_ipc_error)) {
    return false;
  }

  *num_bytes_updated = 0;
  const BOOL get_overlapped_result = ::GetOverlappedResult(
      device_handle, overlapped, num_bytes_updated, FALSE);
  if (get_overlapped_result == FALSE) {
    const DWORD get_overlapped_error = ::GetLastError();
    if (get_overlapped_error == ERROR_BROKEN_PIPE) {
      if (wait_ack) {
        // This is an expected behavior.
        return true;
      }
      LOG(ERROR) << "GetOverlappedResult() failed: ERROR_BROKEN_PIPE";
    } else {
      LOG(ERROR) << "GetOverlappedResult() failed: " << get_overlapped_error;
    }
    *last_ipc_error = IPC_UNKNOWN_ERROR;
    return false;
  }
  return true;
}

bool SendIPCMessage(HANDLE device_handle, HANDLE write_wait_handle,
                    const char *buf, size_t buf_length, int timeout,
                    IPCErrorType *last_ipc_error) {
  if (buf_length == 0) {
    LOG(WARNING) << "buf length is 0";
    *last_ipc_error = IPC_UNKNOWN_ERROR;
    return false;
  }

  DWORD num_bytes_written = 0;
  OVERLAPPED overlapped;
  if (!InitOverlapped(&overlapped, write_wait_handle)) {
    *last_ipc_error = IPC_WRITE_ERROR;
    return false;
  }

  const bool write_file_result = (::WriteFile(
      device_handle, buf, static_cast<DWORD>(buf_length),
      &num_bytes_written, &overlapped) != FALSE);
  const DWORD write_file_error = ::GetLastError();
  if (write_file_result) {
    // ::WriteFile is done as sync operation.
  } else {
    if (write_file_error != ERROR_IO_PENDING) {
      LOG(ERROR) << "WriteFile() failed: " << write_file_error;
      *last_ipc_error = IPC_WRITE_ERROR;
      return false;
    }
    if (!SafeWaitOverlappedResult(
            device_handle, nullptr, timeout, &overlapped,
            &num_bytes_written, last_ipc_error, kSendTypeData)) {
      return false;
    }
  }

  // As we use message-type namedpipe, all the data should be written in one
  // shot. Otherwise, single message will be split into multiple packets.
  if (num_bytes_written != buf_length) {
    LOG(ERROR) << "Data truncated. buf_length: " << buf_length
               << ", num_bytes_written: " << num_bytes_written;
    *last_ipc_error = IPC_UNKNOWN_ERROR;
    return false;
  }
  return true;
}

bool RecvIPCMessage(HANDLE device_handle, HANDLE read_wait_handle, char *buf,
                    size_t *buf_length, int timeout, bool read_type_ack,
                    IPCErrorType *last_ipc_error) {
  if (*buf_length == 0) {
    LOG(WARNING) << "buf length is 0";
    *last_ipc_error = IPC_UNKNOWN_ERROR;
    return false;
  }

  OVERLAPPED overlapped;
  if (!InitOverlapped(&overlapped, read_wait_handle)) {
    *last_ipc_error = IPC_READ_ERROR;
    return false;
  }

  DWORD num_bytes_read = 0;
  const bool read_file_result = (::ReadFile(
      device_handle, buf, static_cast<DWORD>(*buf_length), &num_bytes_read,
      &overlapped) != FALSE);
  const DWORD read_file_error = ::GetLastError();
  if (read_file_result) {
    // ::ReadFile is done as sync operation.
  } else {
    if (read_type_ack && (read_file_error == ERROR_BROKEN_PIPE)) {
      // The client has already disconnected this pipe. This is an expected
      // behavior and do not treat as an error.
      return true;
    }
    if (read_file_error != ERROR_IO_PENDING) {
      LOG(ERROR) << "ReadFile() failed: " << read_file_error;
      *last_ipc_error = IPC_READ_ERROR;
      return false;
    }
    // Actually this is an async operation. Let's wait for its completion.
    if (!SafeWaitOverlappedResult(
            device_handle, nullptr, timeout, &overlapped,
            &num_bytes_read, last_ipc_error, read_type_ack)) {
      return false;
    }
  }

  if (!read_type_ack && (num_bytes_read == 0)) {
    LOG(WARNING) << "Received 0 result.";
  }

  *buf_length = num_bytes_read;

  return true;
}

HANDLE CreateManualResetEvent() {
  return ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
}

// We do not care about the signaled state of the device handle itself.
// This slightly improves the performance.
// See http://msdn.microsoft.com/en-us/library/windows/desktop/aa365538.aspx
void MaybeDisableFileCompletionNotification(HANDLE device_handle) {
  CallOnce(&g_once, &InitAPIsForVistaAndLater);
  if (g_set_file_completion_notification_modes != nullptr) {
    // This is not a mandatory task. Just ignore the actual error (if any).
    g_set_file_completion_notification_modes(device_handle,
                                             FILE_SKIP_SET_EVENT_ON_HANDLE);
  }
}

}  // namespace

IPCServer::IPCServer(const string &name,
                     int32 num_connections,
                     int32 timeout)
    : connected_(false),
      pipe_event_(CreateManualResetEvent()),
      quit_event_(CreateManualResetEvent()),
      timeout_(timeout) {
  IPCPathManager *manager = IPCPathManager::GetIPCPathManager(name);
  string server_address;

  if (!manager->CreateNewPathName() && !manager->LoadPathName()) {
    LOG(ERROR) << "Cannot prepare IPC path name";
    return;
  }

  if (!manager->GetPathName(&server_address)) {
    LOG(ERROR) << "Cannot make IPC path name";
    return;
  }
  DCHECK(!server_address.empty());

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

  // Create a named pipe.
  wstring wserver_address;
  Util::UTF8ToWide(server_address.c_str(), &wserver_address);
  HANDLE handle = ::CreateNamedPipe(wserver_address.c_str(),
                                    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
                                    FILE_FLAG_FIRST_PIPE_INSTANCE,
                                    PIPE_TYPE_MESSAGE |
                                    PIPE_READMODE_MESSAGE |
                                    PIPE_WAIT,
                                    (num_connections <= 0
                                     ? PIPE_UNLIMITED_INSTANCES
                                     : num_connections),
                                    sizeof(request_),
                                    sizeof(response_),
                                    0,
                                    &security_attributes);
  const DWORD create_named_pipe_error = ::GetLastError();
  ::LocalFree(security_attributes.lpSecurityDescriptor);

  if (INVALID_HANDLE_VALUE == handle) {
    LOG(FATAL) << "CreateNamedPipe failed" << create_named_pipe_error;
    return;
  }

  pipe_handle_.reset(handle);

  MaybeDisableFileCompletionNotification(pipe_handle_.get());

  if (!manager->SavePathName()) {
    LOG(ERROR) << "Cannot save IPC path name";
    return;
  }

  connected_ = true;
}

IPCServer::~IPCServer() {
  Terminate();
}

bool IPCServer::Connected() const {
  return connected_;
}

void IPCServer::Terminate() {
  if (server_thread_.get() == nullptr) {
    return;
  }

  if (!server_thread_->IsRunning()) {
    return;
  }

  if (!::SetEvent(quit_event_.get())) {
    LOG(ERROR) << "SetEvent failed";
  }

  // Close the named pipe.
  // This is a workaround for killing child thread
  if (server_thread_.get() != nullptr) {
    server_thread_->Join();
    server_thread_->Terminate();
  }

  connected_ = false;
}

void IPCServer::Loop() {
  IPCErrorType last_ipc_error = IPC_NO_ERROR;

  int successive_connection_failure_count = 0;
  while (connected_) {
    OVERLAPPED overlapped;
    if (!InitOverlapped(&overlapped, pipe_event_.get())) {
      connected_ = false;
      return;
    }

    const BOOL result = ::ConnectNamedPipe(pipe_handle_.get(), &overlapped);
    const DWORD connect_named_pipe_error = ::GetLastError();
    if (result == FALSE) {
      if (connect_named_pipe_error == ERROR_PIPE_CONNECTED) {
        // Already connected. Nothing to do.
      } else if (connect_named_pipe_error == ERROR_NO_DATA) {
        // client already closes the connection
        ::DisconnectNamedPipe(pipe_handle_.get());
        continue;
      } else if (connect_named_pipe_error == ERROR_IO_PENDING) {
        // Actually this is async operation.
        DWORD ignored = 0;
        IPCErrorType ipc_error = IPC_NO_ERROR;
        if (!SafeWaitOverlappedResult(pipe_handle_.get(), quit_event_.get(),
                                      INFINITE, &overlapped, &ignored,
                                      &ipc_error, kReadTypeData)) {
          if (ipc_error == IPC_QUIT_EVENT_SIGNALED) {
            VLOG(1) << "Recived Conrol event from other thread";
            connected_ = false;
            return;
          }
          ++successive_connection_failure_count;
          if (successive_connection_failure_count >=
              kMaxSuccessiveConnectionFailureCount) {
            LOG(ERROR) << "Give up to connect named pipe.";
            connected_ = false;
            return;
          }
          ::DisconnectNamedPipe(pipe_handle_.get());
          continue;
        }
      } else {
        LOG(FATAL) << "Unexpected error: " << connect_named_pipe_error;
      }
    }

    successive_connection_failure_count = 0;
    // Retrieve an incoming message.
    size_t request_size = sizeof(request_);
    if (RecvIPCMessage(pipe_handle_.get(), pipe_event_.get(),
                       &request_[0], &request_size, timeout_,
                       kReadTypeData, &last_ipc_error)) {
      size_t response_size = sizeof(response_);
      if (!Process(&request_[0], request_size,
                   &response_[0], &response_size)) {
        connected_ = false;
      }

      // When Process() returns 0 result, force to call DisconnectNamedPipe()
      // instead of checking ACK message
      if (response_size == 0) {
        LOG(WARNING) << "Process() return 0 result";
        ::DisconnectNamedPipe(pipe_handle_.get());
        continue;
      }

      // Send a response
      SendIPCMessage(pipe_handle_.get(), pipe_event_.get(),
                     &response_[0], response_size, timeout_, &last_ipc_error);
    }

    // Special treatment for Windows per discussion with thatanaka:
    // It's hard to know that client has processed the server's response.
    // We will be able to call ::FlushFileHandles() here, but
    // FlushFileHandles() is blocked if client doesn't call ReadFile(). That
    // means that a malicious user can easily block the server not by calling
    // ReadFile. In order to know the transaction completes successfully,
    // client needs to send an ACK message to the server.

    // Wait ACK-like signal from client for 0.1 second. If we detect the pipe
    // disconnect event, so far so good. If we receive more data, we assume it
    // is an ACK signal (the IPC client of Mozc 1.5.x or earlier does this).
    char ack_request[1] = {0};
    size_t ack_request_size = 1;
    static const int kAckTimeout = 100;
    if (!RecvIPCMessage(pipe_handle_.get(), pipe_event_.get(),
                        ack_request, &ack_request_size, kAckTimeout,
                        kReadTypeACK, &last_ipc_error)) {
      // This case happens when the client did not recive the server's response
      // within timeout. Anyway we will close the connection so that the server
      // will not be blocked.
      LOG(WARNING) << "Client didn't respond within "
                   << kAckTimeout << " msec.";
    }
    ::DisconnectNamedPipe(pipe_handle_.get());
  }

  connected_ = false;
}

// old interface
IPCClient::IPCClient(const string &name)
    : pipe_event_(CreateManualResetEvent()),
      connected_(false),
      ipc_path_manager_(nullptr),
      last_ipc_error_(IPC_NO_ERROR) {
  Init(name, "");
}

IPCClient::IPCClient(const string &name, const string &server_path)
    : pipe_event_(CreateManualResetEvent()),
      connected_(false),
      ipc_path_manager_(nullptr),
      last_ipc_error_(IPC_NO_ERROR) {
  Init(name, server_path);
}

void IPCClient::Init(const string &name, const string &server_path) {
  last_ipc_error_ = IPC_NO_CONNECTION;

  // We should change the mutex based on which IPC server we will talk with.
  ScopedReleaseMutex ipc_mutex(GetClientMutex(name));

  if (ipc_mutex.get() == nullptr) {
    LOG(ERROR) << "IPC mutex is not available";
  } else {
    const int kMutexTimeout = 10 * 1000;  // wait at most 10sec.
    switch (::WaitForSingleObject(ipc_mutex.get(), kMutexTimeout)) {
      case WAIT_TIMEOUT:
        // TODO(taku): with suspend/resume, WaitForSingleObject may
        // return WAIT_TIMEOUT. We have to consider the case
        // in the future.
        LOG(ERROR) << "IPC client was not available even after "
                   << kMutexTimeout << " msec.";
        break;
      case WAIT_ABANDONED:
        DLOG(INFO) << "mutex object was removed";
        break;
      case WAIT_OBJECT_0:
        break;
      default:
        break;
    }
  }

  IPCPathManager *manager = IPCPathManager::GetIPCPathManager(name);
  if (manager == nullptr) {
    LOG(ERROR) << "IPCPathManager::GetIPCPathManager failed";
    return;
  }

  ipc_path_manager_ = manager;

  // TODO(taku): enable them on Mac/Linux
#ifdef DEBUG
  const size_t kMaxTrial = 256;
#else
  const size_t kMaxTrial = 2;
#endif

  for (size_t trial = 0; trial < kMaxTrial; ++trial) {
    string server_address;
    if (!manager->LoadPathName() || !manager->GetPathName(&server_address)) {
      continue;
    }
    wstring wserver_address;
    Util::UTF8ToWide(server_address.c_str(), &wserver_address);

    if (GetNumberOfProcessors() == 1) {
      // When the code is running in single processor environment, sometimes
      // IPC server has not finished the clean-up tasks for the previous IPC
      // session here. So we intentionally call WaitNamedPipe API so that IPC
      // server has a chance to complete clean-up tasks if necessary.
      // NOTE: We cannot set 0 for the wait time because 0 has a special meaning
      // as |NMPWAIT_USE_DEFAULT_WAIT|.
      const DWORD kMinWaitTimeForWaitNamedPipe = 1;
      ::WaitNamedPipe(wserver_address.c_str(), kMinWaitTimeForWaitNamedPipe);
    }

    ScopedHandle new_handle(::CreateFile(wserver_address.c_str(),
                                         GENERIC_READ | GENERIC_WRITE,
                                         0, nullptr, OPEN_EXISTING,
                                         FILE_FLAG_OVERLAPPED |
                                         SECURITY_SQOS_PRESENT |
                                         SECURITY_IDENTIFICATION |
                                         SECURITY_EFFECTIVE_ONLY,
                                         nullptr));
    const DWORD create_file_error = ::GetLastError();
    // ScopedHandle returns nullptr even when it received INVALID_HANDLE_VALUE.
    if (new_handle.get() != nullptr) {
      pipe_handle_.reset(new_handle.take());
      MaybeDisableFileCompletionNotification(pipe_handle_.get());
      if (!manager->IsValidServer(GetServerProcessIdImpl(pipe_handle_.get()),
                                  server_path)) {
        LOG(ERROR) << "Connecting to invalid server";
        last_ipc_error_ = IPC_INVALID_SERVER;
        return;
      }

      last_ipc_error_ = IPC_NO_ERROR;
      connected_ = true;
      return;
    }

    if (ERROR_PIPE_BUSY != create_file_error) {
      LOG(ERROR) << "Server is not running: " << create_file_error;
      manager->Clear();
      continue;
    }

    // wait for 10 second until server is ready
    // TODO(taku): control the timeout via flag.
#ifdef DEBUG
    const int kNamedPipeTimeout = 100000;   // 100 sec
#else
    const int kNamedPipeTimeout = 10000;    // 10 sec
#endif
    DLOG(ERROR) << "Server is busy. waiting for "
                << kNamedPipeTimeout << " msec";
    if (!::WaitNamedPipe(wserver_address.c_str(),
                         kNamedPipeTimeout)) {
      const DWORD wait_named_pipe_error = ::GetLastError();
      LOG(ERROR) << "WaitNamedPipe failed: " << wait_named_pipe_error;
      if ((trial + 1) == kMaxTrial) {
        last_ipc_error_ = IPC_TIMEOUT_ERROR;
        return;
      }
      continue;   // go 2nd trial
    }
  }
}

IPCClient::~IPCClient() {}

bool IPCClient::Connected() const {
  return connected_;
}

bool IPCClient::Call(const char *request, size_t request_size,
                     char *response, size_t *response_size,
                     int32 timeout) {
  last_ipc_error_ = IPC_NO_ERROR;
  if (!connected_) {
    LOG(ERROR) << "IPCClient is not connected";
    last_ipc_error_ = IPC_NO_CONNECTION;
    return false;
  }

  if (!SendIPCMessage(pipe_handle_.get(), pipe_event_.get(), request,
                      request_size, timeout, &last_ipc_error_)) {
    LOG(ERROR) << "SendIPCMessage() failed";
    return false;
  }

  if (!RecvIPCMessage(pipe_handle_.get(), pipe_event_.get(), response,
                      response_size, timeout, kReadTypeData,
                      &last_ipc_error_)) {
    LOG(ERROR) << "RecvIPCMessage() failed";
    return false;
  }

  // Instead of sending ACK message to Server, we simply disconnect the named
  // pile to notify that client can read the message successfully.
  connected_ = false;
  pipe_handle_.reset(INVALID_HANDLE_VALUE);

  return true;
}

}  // namespace mozc

#endif  // OS_WIN
