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

#include "session/session_server.h"

#include <string>

#include "base/logging.h"
#include "base/port.h"
#include "base/scheduler.h"
#include "engine/engine_factory.h"
#include "ipc/ipc.h"
#include "ipc/named_event.h"
#include "session/commands.pb.h"
#include "session/session_handler.h"
#include "session/session_usage_observer.h"
#include "usage_stats/usage_stats_uploader.h"

namespace {

#ifdef OS_WIN
// On Windows, multiple processes can create named pipe objects whose names are
// the same. To reduce the potential risk of DOS, we limit the maximum number
// of pipe instances to 1 here.
const int kNumConnections   = 1;
#else
const int kNumConnections   = 10;
#endif  // OS_WIN

const int kTimeOut = 5000;  // 5000msec
const char kSessionName[] = "session";
const char kEventName[] = "session";

}  // namespace

namespace mozc {

SessionServer::SessionServer()
    : IPCServer(kSessionName, kNumConnections, kTimeOut),
      engine_(EngineFactory::Create()),
      usage_observer_(new session::SessionUsageObserver()),
      session_handler_(new SessionHandler(engine_.get())) {
  using usage_stats::UsageStatsUploader;
  // start session watch dog timer
  session_handler_->StartWatchDog();
  session_handler_->AddObserver(usage_observer_.get());

  // start usage stats timer
  // send usage stats within 5 min later
  // attempt to send every 5 min -- 2 hours.
  Scheduler::AddJob(Scheduler::JobSetting(
      "UsageStatsTimer",
      UsageStatsUploader::kDefaultScheduleInterval,
      UsageStatsUploader::kDefaultScheduleMaxInterval,
      UsageStatsUploader::kDefaultSchedulerDelay,
      UsageStatsUploader::kDefaultSchedulerRandomDelay,
      &UsageStatsUploader::Send,
      NULL));

  // Send a notification event to the UI.
  NamedEventNotifier notifier(kEventName);
  if (!notifier.Notify()) {
    LOG(WARNING) << "NamedEvent " << kEventName << " is not found";
  }
}

SessionServer::~SessionServer() {}

bool SessionServer::Connected() const {
  return (session_handler_.get() != NULL &&
          session_handler_->IsAvailable() &&
          IPCServer::Connected());
}

bool SessionServer::Process(const char *request,
                            size_t request_size,
                            char *response,
                            size_t *response_size) {
  if (session_handler_.get() == NULL) {
    LOG(WARNING) << "handler is not available";
    return false;   // shutdown the server if handler doesn't exist
  }

  commands::Command command;   // can define as a private member?
  if (!command.mutable_input()->ParseFromArray(request, request_size)) {
    LOG(WARNING) << "Invalid request";
    *response_size = 0;
    return true;
  }

  if (!session_handler_->EvalCommand(&command)) {
    LOG(WARNING) << "EvalCommand() returned false. Exiting the loop.";
    *response_size = 0;
    return false;
  }

  string output;
  if (!command.output().SerializeToString(&output)) {
    LOG(WARNING) << "SerializeToString() failed";
    *response_size = 0;
    return true;
  }

  // TODO(taku) automatically increase the buffer.
  // Needs to fix IPCServer as well
  if (*response_size < output.size()) {
    LOG(WARNING) << "response size < output.size";
    *response_size = 0;
    return true;
  }

  ::memcpy(response, output.data(), output.size());
  *response_size = output.size();

  // debug message
  VLOG(2) << command.DebugString();

  return true;
}
}  // namespace mozc
