// 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.

// Session Handler of Mozc server.
// Migrated from ipc/interpreter and session/session_manager

#include "session/session_handler.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/init.h"
#include "base/logging.h"
#include "base/port.h"
#include "base/process.h"
#include "base/singleton.h"
#include "base/stopwatch.h"
#include "base/util.h"
#include "composer/table.h"
#include "config/config.pb.h"
#include "config/config_handler.h"
#include "dictionary/user_dictionary_session_handler.h"
#include "dictionary/user_dictionary_storage.pb.h"
#include "engine/engine_interface.h"
#include "engine/user_data_manager_interface.h"
#include "session/commands.pb.h"
#include "session/generic_storage_manager.h"
#include "session/session.h"
#include "session/session_observer_handler.h"
#ifndef MOZC_DISABLE_SESSION_WATCHDOG
#include "session/session_watch_dog.h"
#else  // MOZC_DISABLE_SESSION_WATCHDOG
// Session watch dog is not aviable from android mozc and nacl mozc for now.
// TODO(kkojima): Remove this guard after
// enabling session watch dog for android.
#endif  // MOZC_DISABLE_SESSION_WATCHDOG
#include "usage_stats/usage_stats.h"

using mozc::usage_stats::UsageStats;

DEFINE_int32(timeout, -1,
             "server timeout. "
             "if sessions get empty for \"timeout\", "
             "shutdown message is automatically emitted");

DEFINE_int32(max_session_size, 64,
             "maximum sessions size. "
             "if size of sessions reaches to \"max_session_size\", "
             "oldest session is removed");

DEFINE_int32(create_session_min_interval, 0,
             "minimum interval (sec) for create session");

DEFINE_int32(watch_dog_interval, 180,
             "watch dog timer intaval (sec)");

DEFINE_int32(last_command_timeout, 3600,
             "remove session if it is not accessed for "
             "\"last_command_timeout\" sec");

DEFINE_int32(last_create_session_timeout, 300,
             "remove session if it is not accessed for "
             "\"last_create_session_timeout\" sec "
             "after create session command");

DEFINE_bool(restricted, false,
            "Launch server with restricted setting");

namespace mozc {

namespace {
bool IsApplicationAlive(const session::SessionInterface *session) {
#ifndef MOZC_DISABLE_SESSION_WATCHDOG
  const commands::ApplicationInfo &info = session->application_info();
  // When the thread/process's current status is unknown, i.e.,
  // if IsThreadAlive/IsProcessAlive functions failed to know the
  // status of the thread/process, return true just in case.
  // Here, we want to kill the session only when the target thread/process
  // are terminated with 100% probability. Otherwise, it's better to do
  // nothing to prevent any side effects.
#ifdef OS_WIN
  if (info.has_thread_id()) {
    return Process::IsThreadAlive(
        static_cast<size_t>(info.thread_id()), true);
  }
#else   // OS_WIN
  if (info.has_process_id()) {
    return Process::IsProcessAlive(
        static_cast<size_t>(info.process_id()), true);
  }
#endif  // OS_WIN
#else  // MOZC_DISABLE_SESSION_WATCHDOG
  // Currently the process is not available through android mozc and nacl mozc.
  // TODO(kkojima): remove this guard after
  // android version supports base/process.cc
#endif  // MOZC_DISABLE_SESSION_WATCHDOG
  return true;
}

bool IsCarrierEmoji(const string &utf8_str) {
  if (Util::CharsLen(utf8_str) != 1) {
    return false;
  }
  const char *utf8_begin = utf8_str.c_str();
  size_t mblen = 0;
  const uint32 ucs4_val = static_cast<uint32>(
      Util::UTF8ToUCS4(utf8_begin, utf8_begin + utf8_str.size(), &mblen));
  const uint32 kMinEmojiPuaCodePoint = 0xFE000;
  const uint32 kMaxEmojiPuaCodePoint = 0xFEEA0;
  return kMinEmojiPuaCodePoint <= ucs4_val && ucs4_val <= kMaxEmojiPuaCodePoint;
}
}  // namespace

SessionHandler::SessionHandler(EngineInterface *engine)
    : is_available_(false),
      max_session_size_(0),
      last_session_empty_time_(Util::GetTime()),
      last_cleanup_time_(0),
      last_create_session_time_(0),
      engine_(engine),
      observer_handler_(new session::SessionObserverHandler()),
      stopwatch_(new Stopwatch),
      user_dictionary_session_handler_(
          new user_dictionary::UserDictionarySessionHandler),
      table_manager_(new composer::TableManager),
      request_(new commands::Request) {
  if (FLAGS_restricted) {
    VLOG(1) << "Server starts with restricted mode";
    // --restricted is almost always specified when mozc_client is inside Job.
    // The typical case is Startup processes on Vista.
    // On Vista, StartUp processes are in Job for 60 seconds. In order
    // to launch new mozc_server inside sandbox, we set the timeout
    // to be 60sec. Client application hopefully re-launch mozc_server.
    FLAGS_timeout = 60;
    FLAGS_max_session_size = 8;
    FLAGS_watch_dog_interval = 15;
    FLAGS_last_create_session_timeout = 60;
    FLAGS_last_command_timeout = 60;
  }

#ifndef MOZC_DISABLE_SESSION_WATCHDOG
  session_watch_dog_.reset(new SessionWatchDog(FLAGS_watch_dog_interval));
#else  // MOZC_DISABLE_SESSION_WATCHDOG
  // Session watch dog is not aviable from android mozc and nacl mozc for now.
  // TODO(kkojima): Remove this guard after
  // enabling session watch dog for android.
#endif  // MOZC_DISABLE_SESSION_WATCHDOG

  // allow [2..128] sessions
  max_session_size_ = max(2, min(FLAGS_max_session_size, 128));
  session_map_.reset(new SessionMap(max_session_size_));

  if (engine_ == NULL) {
    return;
  }

  // everything is OK
  is_available_ = true;
}

SessionHandler::~SessionHandler() {
  for (SessionElement *element =
           const_cast<SessionElement *>(session_map_->Head());
       element != NULL; element = element->next) {
    delete element->value;
    element->value = NULL;
  }
  session_map_->Clear();
#ifndef MOZC_DISABLE_SESSION_WATCHDOG
  if (session_watch_dog_->IsRunning()) {
    session_watch_dog_->Terminate();
  }
#else  // MOZC_DISABLE_SESSION_WATCHDOG
  // Session watch dog is not aviable from android mozc and nacl mozc for now.
  // TODO(kkojima): Remove this guard after
  // enabling session watch dog for android.
#endif  // MOZC_DISABLE_SESSION_WATCHDOG
}

bool SessionHandler::IsAvailable() const {
  return is_available_;
}

bool SessionHandler::StartWatchDog() {
#ifndef MOZC_DISABLE_SESSION_WATCHDOG
  if (!session_watch_dog_->IsRunning()) {
    session_watch_dog_->Start();
  }
  return session_watch_dog_->IsRunning();
#else  // MOZC_DISABLE_SESSION_WATCHDOG
  // Session watch dog is not aviable from android mozc and nacl mozc for now.
  // TODO(kkojima): Remove this guard after
  // enabling session watch dog for android.
  return false;
#endif  // MOZC_DISABLE_SESSION_WATCHDOG
}

void SessionHandler::ReloadSession() {
  observer_handler_->Reload();
  ReloadConfig();
}

void SessionHandler::ReloadConfig() {
  const composer::Table *table = table_manager_->GetTable(
      *request_, config::ConfigHandler::GetConfig());
  for (SessionElement *element =
           const_cast<SessionElement *>(session_map_->Head());
       element != NULL; element = element->next) {
    if (element->value != NULL) {
      element->value->ReloadConfig();
      element->value->SetRequest(request_.get());
      element->value->SetTable(table);
    }
  }
}

bool SessionHandler::SyncData(commands::Command *command) {
  VLOG(1) << "Syncing user data";
  engine_->GetUserDataManager()->Sync();
  return true;
}

bool SessionHandler::Shutdown(commands::Command *command) {
  VLOG(1) << "Shutdown server";
  SyncData(command);
  ReloadSession();   // for saving log_commands
  is_available_ = false;
  UsageStats::IncrementCount("ShutDown");
  return true;
}

bool SessionHandler::Reload(commands::Command *command) {
  VLOG(1) << "Reloading server";
  ReloadSession();
  engine_->Reload();
  RunReloaders();  // call all reloaders defined in .cc file
  return true;
}

bool SessionHandler::ClearUserHistory(commands::Command *command) {
  VLOG(1) << "Clearing user history";
  engine_->GetUserDataManager()->ClearUserHistory();
  UsageStats::IncrementCount("ClearUserHistory");
  return true;
}

bool SessionHandler::ClearUserPrediction(commands::Command *command) {
  VLOG(1) << "Clearing user prediction";
  engine_->GetUserDataManager()->ClearUserPrediction();
  UsageStats::IncrementCount("ClearUserPrediction");
  return true;
}

bool SessionHandler::ClearUnusedUserPrediction(commands::Command *command) {
  VLOG(1) << "Clearing unused user prediction";
  engine_->GetUserDataManager()->ClearUnusedUserPrediction();
  UsageStats::IncrementCount("ClearUnusedUserPrediction");
  return true;
}

bool SessionHandler::GetStoredConfig(commands::Command *command) {
  VLOG(1) << "Getting stored config";
  // Ensure the onmemory config is same as the locally stored one
  // because the local data could be changed by sync.
  ReloadConfig();

  // Use GetStoredConfig instead of GetConfig because GET_CONFIG
  // command should return raw stored config, which is not
  // affected by imposed config.
  if (!config::ConfigHandler::GetStoredConfig(
          command->mutable_output()->mutable_config())) {
    LOG(WARNING) << "cannot get config";
    return false;
  }
  return true;
}

bool SessionHandler::SetStoredConfig(commands::Command *command) {
  VLOG(1) << "Setting user config";
  if (!command->input().has_config()) {
    LOG(WARNING) << "config is empty";
    return false;
  }

  const mozc::config::Config &config = command->input().config();
  if (!config::ConfigHandler::SetConfig(config)) {
    return false;
  }

  command->mutable_output()->mutable_config()->CopyFrom(config);
  Reload(command);
  UsageStats::IncrementCount("SetConfig");

  return true;
}

bool SessionHandler::SetImposedConfig(commands::Command *command) {
  VLOG(1) << "Setting imposed config";
  if (!command->input().has_config()) {
    LOG(WARNING) << "config is empty";
    return false;
  }

  const mozc::config::Config &config = command->input().config();
  config::ConfigHandler::SetImposedConfig(config);

  Reload(command);

  return true;
}

bool SessionHandler::SetRequest(commands::Command *command) {
  VLOG(1) << "Setting client's request";
  if (!command->input().has_request()) {
    LOG(WARNING) << "request is empty";
    return false;
  }

  request_->CopyFrom(command->input().request());

  Reload(command);

  return true;
}

bool SessionHandler::InsertToStorage(commands::Command *command) {
  VLOG(1) << "Insert to generic storage";
  if (!command->input().has_storage_entry()) {
    LOG(WARNING) << "No storage_entry";
    return false;
  }
  const commands::GenericStorageEntry &storage_entry =
      command->input().storage_entry();
  if (!storage_entry.has_type() ||
      !storage_entry.has_key() ||
      storage_entry.value().size() == 0) {
    LOG(WARNING) << "storage_entry lacks some fields.";
    return false;
  }

  GenericStorageInterface *storage =
      GenericStorageManagerFactory::GetStorage(storage_entry.type());
  if (!storage) {
    LOG(WARNING) << "No storage found";
    return false;
  }

  for (int i = 0; i < storage_entry.value_size(); ++i) {
    const string &value = storage_entry.value(i);
    storage->Insert(value, value.c_str());
  }

  if (storage_entry.type() == commands::GenericStorageEntry::EMOJI_HISTORY) {
    for (int i = 0; i < storage_entry.value_size(); ++i) {
      if (IsCarrierEmoji(storage_entry.value(i))) {
        UsageStats::IncrementCount("CommitCarrierEmoji");
      } else {
        UsageStats::IncrementCount("CommitUnicodeEmoji");
      }
    }
  }

  return true;
}

bool SessionHandler::ReadAllFromStorage(commands::Command *command) {
  VLOG(1) << "Read all from storage";
  commands::Output *output = command->mutable_output();
  if (!command->input().has_storage_entry()) {
    LOG(WARNING) << "No storage_entry";
    return false;
  }
  if (!command->input().storage_entry().has_type()) {
    LOG(WARNING) << "storage_entry lacks type fields.";
    return false;
  }

  commands::GenericStorageEntry::StorageType storage_type =
    command->input().storage_entry().type();
  GenericStorageInterface *storage =
      GenericStorageManagerFactory::GetStorage(storage_type);
  if (!storage) {
    LOG(WARNING) << "No storage found";
    return false;
  }

  vector<string> result;
  storage->GetAllValues(&result);
  output->mutable_storage_entry()->set_type(storage_type);
  for (size_t i = 0; i < result.size(); ++i) {
    output->mutable_storage_entry()->add_value(result[i]);
  }
  return true;
}

bool SessionHandler::ClearStorage(commands::Command *command) {
  VLOG(1) << "Clear storage";
  commands::Output *output = command->mutable_output();
  if (!command->input().has_storage_entry()) {
    LOG(WARNING) << "No storage_entry";
    return false;
  }
  if (!command->input().storage_entry().has_type()) {
    LOG(WARNING) << "storage_entry lacks type fields.";
    return false;
  }

  commands::GenericStorageEntry::StorageType storage_type =
    command->input().storage_entry().type();
  GenericStorageInterface *storage =
      GenericStorageManagerFactory::GetStorage(storage_type);
  if (!storage) {
    LOG(WARNING) << "No storage found";
    return false;
  }
  output->mutable_storage_entry()->set_type(storage_type);
  return storage->Clear();
}

bool SessionHandler::EvalCommand(commands::Command *command) {
  if (!is_available_) {
    LOG(ERROR) << "SessionHandler is not available.";
    return false;
  }

  bool eval_succeeded = false;
  stopwatch_->Reset();
  stopwatch_->Start();

  switch (command->input().type()) {
    case commands::Input::CREATE_SESSION:
      eval_succeeded = CreateSession(command);
      break;
    case commands::Input::DELETE_SESSION:
      eval_succeeded = DeleteSession(command);
      break;
    case commands::Input::SEND_KEY:
      eval_succeeded = SendKey(command);
      break;
    case commands::Input::TEST_SEND_KEY:
      eval_succeeded = TestSendKey(command);
      break;
    case commands::Input::SEND_COMMAND:
      eval_succeeded = SendCommand(command);
      break;
    case commands::Input::SYNC_DATA:
      eval_succeeded = SyncData(command);
      break;
    case commands::Input::CLEAR_USER_HISTORY:
      eval_succeeded = ClearUserHistory(command);
      break;
    case commands::Input::CLEAR_USER_PREDICTION:
      eval_succeeded = ClearUserPrediction(command);
      break;
    case commands::Input::CLEAR_UNUSED_USER_PREDICTION:
      eval_succeeded = ClearUnusedUserPrediction(command);
      break;
    case commands::Input::GET_CONFIG:
      eval_succeeded = GetStoredConfig(command);
      break;
    case commands::Input::SET_CONFIG:
      eval_succeeded = SetStoredConfig(command);
      break;
    case commands::Input::SET_IMPOSED_CONFIG:
      eval_succeeded = SetImposedConfig(command);
      break;
    case commands::Input::SET_REQUEST:
      eval_succeeded = SetRequest(command);
      break;
    case commands::Input::SHUTDOWN:
      eval_succeeded = Shutdown(command);
      break;
    case commands::Input::RELOAD:
      eval_succeeded = Reload(command);
      break;
    case commands::Input::CLEANUP:
      eval_succeeded = Cleanup(command);
      break;
    case commands::Input::INSERT_TO_STORAGE:
      eval_succeeded = InsertToStorage(command);
      break;
    case commands::Input::READ_ALL_FROM_STORAGE:
      eval_succeeded = ReadAllFromStorage(command);
      break;
    case commands::Input::CLEAR_STORAGE:
      eval_succeeded = ClearStorage(command);
      break;
    case commands::Input::SEND_USER_DICTIONARY_COMMAND:
      eval_succeeded = SendUserDictionaryCommand(command);
      break;
    case commands::Input::NO_OPERATION:
      eval_succeeded = NoOperation(command);
      break;
    default:
      eval_succeeded = false;
  }

  if (eval_succeeded) {
    UsageStats::IncrementCount("SessionAllEvent");
    if (command->input().type() != commands::Input::CREATE_SESSION) {
      // Fill a session ID even if command->input() doesn't have a id to ensure
      // that response size should not be 0, which causes disconnection of IPC.
      command->mutable_output()->set_id(command->input().id());
    }
  } else {
    command->mutable_output()->set_id(0);
    command->mutable_output()->set_error_code(
        commands::Output::SESSION_FAILURE);
  }

  if (eval_succeeded) {
    // TODO(komatsu): Make sre if checking eval_succeeded is necessary or not.
    observer_handler_->EvalCommandHandler(*command);
  }

  stopwatch_->Stop();
  UsageStats::UpdateTiming("ElapsedTimeUSec",
                           stopwatch_->GetElapsedMicroseconds());

  return is_available_;
}

session::SessionInterface *SessionHandler::NewSession() {
  return new session::Session(engine_);
}

void SessionHandler::AddObserver(session::SessionObserverInterface *observer) {
  observer_handler_->AddObserver(observer);
}

bool SessionHandler::SendKey(commands::Command *command) {
  const SessionID id = command->input().id();
  session::SessionInterface **session = session_map_->MutableLookup(id);
  if (session == NULL || *session == NULL) {
    LOG(WARNING) << "SessionID " << id << " is not available";
    return false;
  }
  (*session)->SendKey(command);
  return true;
}

bool SessionHandler::TestSendKey(commands::Command *command) {
  const SessionID id = command->input().id();
  session::SessionInterface **session = session_map_->MutableLookup(id);
  if (session == NULL || *session == NULL) {
    LOG(WARNING) << "SessionID " << id << " is not available";
    return false;
  }
  (*session)->TestSendKey(command);
  return true;
}

bool SessionHandler::SendCommand(commands::Command *command) {
  const SessionID id = command->input().id();
  session::SessionInterface **session =
    const_cast<session::SessionInterface **>(session_map_->Lookup(id));
  if (session == NULL || *session == NULL) {
    LOG(WARNING) << "SessionID " << id << " is not available";
    return false;
  }
  (*session)->SendCommand(command);
  return true;
}

bool SessionHandler::CreateSession(commands::Command *command) {
  // prevent DOS attack
  // don't allow CreateSession in very short period.
  const int create_session_minimum_interval =
      max(0, min(FLAGS_create_session_min_interval, 10));

  uint64 current_time = Util::GetTime();
  if (last_create_session_time_ != 0 &&
      (current_time - last_create_session_time_) <
      create_session_minimum_interval) {
    return false;
  }

  last_create_session_time_ = current_time;

  // if session map is FULL, remove the oldest item from the LRU
  SessionElement *oldest_element = NULL;
  if (session_map_->Size() >= max_session_size_) {
    oldest_element = const_cast<SessionElement *>(session_map_->Tail());
    if (oldest_element == NULL) {
      LOG(ERROR) << "oldest SessionElement is NULL";
      return false;
    }
    delete oldest_element->value;
    oldest_element->value = NULL;
    session_map_->Erase(oldest_element->key);
    VLOG(1) << "Session is FULL, oldest SessionID "
            << oldest_element->key << " is removed";
  }

  session::SessionInterface *session = NewSession();
  if (session == NULL) {
    LOG(ERROR) << "Cannot allocate new Session";
    return false;
  }

  const SessionID new_id = CreateNewSessionID();
  SessionElement *element = session_map_->Insert(new_id);
  element->value = session;
  command->mutable_output()->set_id(new_id);

  // The oldes item should be reused
  DCHECK(oldest_element == NULL || oldest_element == element);

  if (command->input().has_capability()) {
    session->set_client_capability(command->input().capability());
  }

  if (command->input().has_application_info()) {
    session->set_application_info(command->input().application_info());
#ifdef __native_client__
    if (command->input().application_info().has_timezone_offset()) {
      Util::SetTimezoneOffset(
          command->input().application_info().timezone_offset());
    }
#endif  // __native_client__
  }

  // Ensure the onmemory config is same as the locally stored one
  // because the local data could be changed by sync.
  ReloadConfig();

  // session is not empty.
  last_session_empty_time_ = 0;

  UsageStats::IncrementCount("SessionCreated");

  return true;
}

bool SessionHandler::DeleteSession(commands::Command *command) {
  DeleteSessionID(command->input().id());
  engine_->GetUserDataManager()->Sync();
  return true;
}

// Scan all sessions and find and delete session which is either
// (a) The session is not activated for 60min
// (b) The session is created but not accessed for 5min
// (c) application is already terminated.
// Also, if timeout is enabled, shutdown server if there is
// no active session and client doesn't send any conversion
// request to the server for FLAGS_timeout sec.
bool SessionHandler::Cleanup(commands::Command *command) {
  const uint64 current_time = Util::GetTime();

  // suspend/hibernation may happen
  uint64 suspend_time = 0;
#ifndef MOZC_DISABLE_SESSION_WATCHDOG
  if (last_cleanup_time_ != 0 &&
      session_watch_dog_->IsRunning() &&
      (current_time - last_cleanup_time_) >
      2 * session_watch_dog_->interval()) {
    suspend_time = current_time - last_cleanup_time_ -
        session_watch_dog_->interval();
    LOG(WARNING) << "server went to suspend mode for "
                 << suspend_time << " sec";
  }
#else  // MOZC_DISABLE_SESSION_WATCHDOG
  // Session watch dog is not aviable from android mozc and nacl mozc for now.
  // TODO(kkojima): Remove this guard after
  // enabling session watch dog for android.
#endif  // MOZC_DISABLE_SESSION_WATCHDOG

  // allow [1..600] sec. default: 300
  const uint64 create_session_timeout =
      suspend_time +
      max(1, min(FLAGS_last_create_session_timeout, 600));

  // allow [10..7200] sec. default 3600
  const uint64 last_command_timeout =
      suspend_time +
      max(10, min(FLAGS_last_command_timeout, 7200));

  vector<SessionID> remove_ids;
  for (SessionElement *element =
           const_cast<SessionElement *>(session_map_->Head());
       element != NULL; element = element->next) {
    session::SessionInterface *session = element->value;
    if (!IsApplicationAlive(session)) {
      VLOG(2) << "Application is not alive. Removing: " << element->key;
      remove_ids.push_back(element->key);
    } else if (session->last_command_time() == 0) {
      // no command is exectuted
      if ((current_time - session->create_session_time()) >=
          create_session_timeout) {
        remove_ids.push_back(element->key);
      }
    } else {  // some commands are executed already
      if ((current_time - session->last_command_time()) >=
          last_command_timeout) {
        remove_ids.push_back(element->key);
      }
    }
  }

  for (size_t i = 0; i < remove_ids.size(); ++i) {
    DeleteSessionID(remove_ids[i]);
    VLOG(1) << "Session ID " << remove_ids[i] << " is removed by server";
  }

  // Sync all data. This is a regression bug fix http://b/3033708
  engine_->GetUserDataManager()->Sync();

  // timeout is enabled.
  if (FLAGS_timeout > 0 &&
      last_session_empty_time_ != 0 &&
      (current_time - last_session_empty_time_)
      >= suspend_time + FLAGS_timeout) {
    Shutdown(command);
  }

  last_cleanup_time_ = current_time;

  return true;
}

bool SessionHandler::SendUserDictionaryCommand(commands::Command *command) {
  if (!command->input().has_user_dictionary_command()) {
    return false;
  }
  user_dictionary::UserDictionaryCommandStatus status;
  const bool result = user_dictionary_session_handler_->Evaluate(
      command->input().user_dictionary_command(), &status);
  if (result) {
    status.Swap(
        command->mutable_output()->mutable_user_dictionary_command_status());
  }
  return result;
}

bool SessionHandler::NoOperation(commands::Command *command) {
  return true;
}

// Create Random Session ID in order to make the session id unpredicable
SessionID SessionHandler::CreateNewSessionID() {
  SessionID id = 0;
  while (true) {
    Util::GetRandomSequence(reinterpret_cast<char *>(&id), sizeof(id));
    // don't allow id == 0, as it is reserved for
    // "invalid id"
    if (id != 0 && !session_map_->HasKey(id)) {
      break;
    }

    LOG(WARNING) << "Session ID " << id << " is already used. retry";
  }

  return id;
}

bool SessionHandler::DeleteSessionID(SessionID id) {
  session::SessionInterface **session = session_map_->MutableLookup(id);
  if (session == NULL || *session == NULL) {
    LOG_IF(WARNING, id != 0) << "cannot find SessionID " << id;
    return false;
  }
  delete *session;

  session_map_->Erase(id);   // remove from LRU

  // if session gets empty, save the timestamp
  if (last_session_empty_time_ == 0 &&
      session_map_->Size() == 0) {
    last_session_empty_time_ = Util::GetTime();
  }

  return true;
}
}  // namespace mozc
