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

// TODO(horo): write tests.

#include <ppapi/cpp/instance.h>
#include <ppapi/cpp/module.h>
#include <ppapi/cpp/var.h>
#include <ppapi/utility/completion_callback_factory.h>

#include <queue>
#include <string>

#include "base/logging.h"
#include "base/mutex.h"
#include "base/pepper_file_util.h"
#include "base/scheduler.h"
#include "base/thread.h"
#include "base/util.h"
#include "base/version.h"
#include "chrome/nacl/dictionary_downloader.h"
#include "config/config_handler.h"
#include "config/config.pb.h"
#include "data_manager/packed/packed_data_manager.h"
#include "dictionary/user_dictionary_util.h"
#include "dictionary/user_pos.h"
#include "engine/engine_factory.h"
#include "net/http_client.h"
#include "net/http_client_pepper.h"
#include "net/jsoncpp.h"
#include "net/json_util.h"
#include "session/commands.pb.h"
#include "session/session_handler.h"
#include "session/session_usage_observer.h"
#include "usage_stats/usage_stats.h"
#include "usage_stats/usage_stats_uploader.h"

using mozc::net::JsonUtil;

namespace mozc {
namespace {

// TODO(horo): Need to confirm that this 1024 is OK.
const uint32 kFileIoFileSystemExpectedSize = 1024;

// Wrapper class of pthread_cond.
class Condition {
 public:
  Condition() {
    pthread_cond_init(&cond_, NULL);
  }
  ~Condition() {
    pthread_cond_destroy(&cond_);
  }
  int signal() {
    return pthread_cond_signal(&cond_);
  }
  int broadcast() {
    return pthread_cond_broadcast(&cond_);
  }
  void wait(Mutex *mutex) {
    pthread_cond_wait(&cond_, mutex->raw_mutex());
  }

 private:
  pthread_cond_t cond_;
  DISALLOW_COPY_AND_ASSIGN(Condition);
};

// Simple blocking queue implementation.
template<typename T>
class BlockingQueue {
 public:
  BlockingQueue()
    : blocked_count_(0),
      is_stopped_(false) {
  }

  ~BlockingQueue() {
    stop();
  }

  void stop() {
    scoped_lock l(&mutex_);
    is_stopped_ = true;
    condition_.broadcast();
    while (blocked_count_) {
      condition_.wait(&mutex_);
    }
  }

  void put(T element) {
    scoped_lock l(&mutex_);
    queue_.push(element);
    condition_.signal();
  }

  T take(bool *stopped) {
    if (stopped) {
      *stopped = false;
    }
    scoped_lock l(&mutex_);
    ++blocked_count_;
    while (queue_.empty() && !is_stopped_) {
      condition_.wait(&mutex_);
    }
    --blocked_count_;

    if (is_stopped_) {
      condition_.broadcast();
      if (stopped) {
        *stopped = true;
      }
    }
    const T front_element = queue_.front();
    queue_.pop();
    return front_element;
  }

 private:
  Mutex mutex_;
  Condition condition_;
  int blocked_count_;
  bool is_stopped_;
  queue<T> queue_;

  DISALLOW_COPY_AND_ASSIGN(BlockingQueue);
};

}  // namespace

namespace session {

class MozcSessionHandlerThread : public Thread {
 public:
  MozcSessionHandlerThread(
      pp::Instance *instance,
      BlockingQueue<Json::Value*> *queue)
    : instance_(instance), message_queue_(queue), factory_(this) {
  }

  virtual ~MozcSessionHandlerThread() {
  }

  virtual void Run() {
    Util::SetRandomSeed(static_cast<uint32>(Util::GetTime()));
    RegisterPepperInstanceForHTTPClient(instance_);
#ifdef GOOGLE_JAPANESE_INPUT_BUILD
    const bool filesystem_available =
        PepperFileUtil::Initialize(instance_, kFileIoFileSystemExpectedSize);
    if (!filesystem_available) {
      // Pepper file system is not available, so ignore the big dictionary and
      // use the small dictionary.
      LoadDictionary();
    } else if (!LoadBigDictionary(&big_dictionary_version_)) {
      LOG(ERROR) << "LoadBigDictionary error";
      StartDownloadDictionary();
      LoadDictionary();
    } else if (big_dictionary_version_ !=
                   Version::GetMozcNaclDictionaryVersion()) {
      LOG(ERROR) << "LoadBigDictionary version miss match "
                 << big_dictionary_version_ << " :"
                 << Version::GetMozcNaclDictionaryVersion();
      StartDownloadDictionary();
    }
#else  // GOOGLE_JAPANESE_INPUT_BUILD
    PepperFileUtil::Initialize(instance_, kFileIoFileSystemExpectedSize);
    LoadDictionary();
#endif  // GOOGLE_JAPANESE_INPUT_BUILD
    user_pos_.reset(
        new UserPOS(
            packed::PackedDataManager::GetUserPosManager()->GetUserPOSData()));

    engine_.reset(mozc::EngineFactory::Create());
    handler_.reset(new SessionHandler(engine_.get()));

#ifdef GOOGLE_JAPANESE_INPUT_BUILD
    usage_observer_.reset(new SessionUsageObserver());
    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",
        usage_stats::UsageStatsUploader::kDefaultScheduleInterval,
        usage_stats::UsageStatsUploader::kDefaultScheduleMaxInterval,
        usage_stats::UsageStatsUploader::kDefaultSchedulerDelay,
        usage_stats::UsageStatsUploader::kDefaultSchedulerRandomDelay,
        &MozcSessionHandlerThread::SendUsageStats,
        this));
#endif  // GOOGLE_JAPANESE_INPUT_BUILD

    // Gets the current config.
    config::Config config;
    config::ConfigHandler::GetStoredConfig(&config);
    // Sends "InitializeDone" message to JavaScript side code.
    Json::Value message(Json::objectValue);
    message["event"] = Json::objectValue;
    message["event"]["type"] = "InitializeDone";
    JsonUtil::ProtobufMessageToJsonValue(config, &message["event"]["config"]);
    message["event"]["version"] = Version::GetMozcVersion();
#ifdef GOOGLE_JAPANESE_INPUT_BUILD
    message["event"]["big_dictionary_version"] = big_dictionary_version_;
#endif  // GOOGLE_JAPANESE_INPUT_BUILD

    pp::Module::Get()->core()->CallOnMainThread(
        0,
        factory_.NewCallback(
            &MozcSessionHandlerThread::PostMessage,
            Json::FastWriter().write(message)));

    while (true) {
      bool stopped = false;
      scoped_ptr<Json::Value> message;
      message.reset(message_queue_->take(&stopped));
      if (stopped) {
        LOG(ERROR) << " message_queue_ stopped";
        return;
      }
      if (!message->isMember("id") ||
          (!message->isMember("cmd") && !message->isMember("event"))) {
        LOG(ERROR) << "request error";
        continue;
      }
      Json::Value response(Json::objectValue);
      response["id"] = (*message)["id"];
      if (message->isMember("cmd")) {
        commands::Command command;
        JsonUtil::JsonValueToProtobufMessage((*message)["cmd"], &command);
        handler_->EvalCommand(&command);
        JsonUtil::ProtobufMessageToJsonValue(command, &response["cmd"]);
      }
      if (message->isMember("event") && (*message)["event"].isMember("type")) {
        response["event"] = Json::objectValue;
        const string event_type = (*message)["event"]["type"].asString();
        response["event"]["type"] = event_type;
        if (event_type == "SyncToFile") {
          response["event"]["result"] = PepperFileUtil::SyncMmapToFile();
        } else if (event_type == "GetVersionInfo") {
          response["event"]["version"] = Version::GetMozcVersion();
#ifdef GOOGLE_JAPANESE_INPUT_BUILD
          response["event"]["big_dictionary_version"] = big_dictionary_version_;
          response["event"]["big_dictionary_state"] = GetBigDictionaryState();
#endif  // GOOGLE_JAPANESE_INPUT_BUILD
        } else if (event_type == "GetPosList") {
          GetPosList(&response);
        } else if (event_type == "IsValidReading") {
          IsValidReading((*message)["event"], &response);
        } else {
          response["event"]["error"] = "Unsupported event";
        }
      }

      pp::Module::Get()->core()->CallOnMainThread(
          0,
          factory_.NewCallback(
              &MozcSessionHandlerThread::PostMessage,
              Json::FastWriter().write(response)));
    }
  }

  void PostMessage(int32_t result, const string &message) {
    instance_->PostMessage(message);
  }

 private:
#ifdef GOOGLE_JAPANESE_INPUT_BUILD
  // Loads the big dictionary
  // Returns true and sets the dictionary version if successful.
  bool LoadBigDictionary(string *version) {
    string buffer;
    // The big dictionary data is in the user's HTML5 file system.
    if (!PepperFileUtil::ReadBinaryFile("/zipped_data_google", &buffer)) {
      LOG(ERROR) << "PepperFileUtil::ReadBinaryFile error";
      return false;
    }
    scoped_ptr<mozc::packed::PackedDataManager>
        data_manager(new mozc::packed::PackedDataManager());
    if (!data_manager->InitWithZippedData(buffer)) {
      LOG(ERROR) << "InitWithZippedData error";
      return false;
    }
    *version = data_manager->GetDictionaryVersion();
    mozc::packed::RegisterPackedDataManager(data_manager.release());
    return true;
  }

  // Starts downloading the big dictionary.
  void StartDownloadDictionary() {
    downloader_.reset(new chrome::nacl::DictionaryDownloader(
        Version::GetMozcNaclDictionaryUrl(),
        "/zipped_data_google"));
    downloader_->SetOption(10 * 60 * 1000,  // 10 minutes start delay
                           20 * 60 * 1000,  // + [0-20] minutes random delay
                           30 * 60 * 1000,  // retry_interval 30 min
                           4,  // retry interval [30, 60, 120, 240, 240, 240...]
                           10);  // 10 retries
    downloader_->StartDownload();
  }
#endif  // GOOGLE_JAPANESE_INPUT_BUILD

  // Loads the dictionary.
  void LoadDictionary() {
    string output;
    HTTPClient::Option option;
    option.timeout = 200000;
    option.max_data_size = 100 * 1024 * 1024;  // 100MB
    // System dictionary data is in the user's Extensions directory.
#ifdef GOOGLE_JAPANESE_INPUT_BUILD
    const string data_file_name = "./zipped_data_chromeos";
#else  // GOOGLE_JAPANESE_INPUT_BUILD
    const string data_file_name = "./zipped_data_oss";
#endif  // GOOGLE_JAPANESE_INPUT_BUILD
    CHECK(HTTPClient::Get(data_file_name, option, &output));
    scoped_ptr<mozc::packed::PackedDataManager>
        data_manager(new mozc::packed::PackedDataManager());
    CHECK(data_manager->InitWithZippedData(output));
    mozc::packed::RegisterPackedDataManager(data_manager.release());
  }

#ifdef GOOGLE_JAPANESE_INPUT_BUILD
  // Returns BigDictionaryState
  //   0x00: Correct version BigDictionary is found.
  //   0x1-: BigDictionary is not found.
  //   0x2-: BigDictionary version miss match.
  //   0x-*: Status of the downloader.
  int GetBigDictionaryState() {
    if (big_dictionary_version_ == Version::GetMozcNaclDictionaryVersion()) {
      return 0;
    }
    int status = 0;
    if (big_dictionary_version_.empty()) {
      status = 0x10;
    } else {
      status = 0x20;
    }
    if (downloader_.get()) {
      status += downloader_->GetStatus();
    }
    return status;
  }

  static bool SendUsageStats(void *data) {
    MozcSessionHandlerThread *self =
        static_cast<MozcSessionHandlerThread *>(data);
    usage_stats::UsageStats::SetInteger("BigDictionaryState",
                                        self->GetBigDictionaryState());
    return usage_stats::UsageStatsUploader::Send(NULL);
  }
#endif  // GOOGLE_JAPANESE_INPUT_BUILD

  void GetPosList(Json::Value *response) {
    (*response)["event"]["posList"] = Json::Value(Json::arrayValue);
    Json::Value *pos_list = &(*response)["event"]["posList"];
    vector<string> tmp_pos_vec;
    user_pos_->GetPOSList(&tmp_pos_vec);
    for (int i = 0; i < tmp_pos_vec.size(); ++i) {
      (*pos_list)[i] = Json::Value(Json::objectValue);
      const user_dictionary::UserDictionary::PosType pos_type =
          UserDictionaryUtil::ToPosType(tmp_pos_vec[i].c_str());
      (*pos_list)[i]["type"] =
          Json::Value(user_dictionary::UserDictionary::PosType_Name(pos_type));
      (*pos_list)[i]["name"] = Json::Value(tmp_pos_vec[i]);
    }
  }

  void IsValidReading(const Json::Value &event, Json::Value *response) {
    if (!event.isMember("data")) {
      (*response)["event"]["result"] = false;
      return;
    }
    (*response)["event"]["data"] = event["data"].asString();
    (*response)["event"]["result"] =
        UserDictionaryUtil::IsValidReading(event["data"].asString());
  }

  pp::Instance *instance_;
  BlockingQueue<Json::Value *> *message_queue_;
  pp::CompletionCallbackFactory<MozcSessionHandlerThread> factory_;
  scoped_ptr<EngineInterface> engine_;
  scoped_ptr<SessionHandlerInterface> handler_;
  scoped_ptr<const UserPOSInterface> user_pos_;
#ifdef GOOGLE_JAPANESE_INPUT_BUILD
  scoped_ptr<SessionUsageObserver> usage_observer_;
  scoped_ptr<chrome::nacl::DictionaryDownloader> downloader_;
  string big_dictionary_version_;
#endif  // GOOGLE_JAPANESE_INPUT_BUILD
  DISALLOW_COPY_AND_ASSIGN(MozcSessionHandlerThread);
};

class NaclSessionHandlerInstance : public pp::Instance {
 public:
  explicit NaclSessionHandlerInstance(PP_Instance instance);
  virtual ~NaclSessionHandlerInstance() {}
  virtual void HandleMessage(const pp::Var &var_message);

 private:
  void CheckStatusAndStartMozcSessionHandlerThread();

  scoped_ptr<MozcSessionHandlerThread> mozc_thread_;
  BlockingQueue<Json::Value *> message_queue_;

  DISALLOW_COPY_AND_ASSIGN(NaclSessionHandlerInstance);
};

NaclSessionHandlerInstance::NaclSessionHandlerInstance(PP_Instance instance)
    : pp::Instance(instance) {
  mozc_thread_.reset(new MozcSessionHandlerThread(this, &message_queue_));
  mozc_thread_->Start();
}

void NaclSessionHandlerInstance::HandleMessage(const pp::Var &var_message) {
  if (!var_message.is_string()) {
    return;
  }

  scoped_ptr<Json::Value> message(new Json::Value);
  if (Json::Reader().parse(var_message.AsString(), *message.get())) {
    message_queue_.put(message.release());
  }
}

class NaclSessionHandlerModule : public pp::Module {
 public:
  NaclSessionHandlerModule() : pp::Module() {
  }
  virtual ~NaclSessionHandlerModule() {}

 protected:
  virtual pp::Instance *CreateInstance(PP_Instance instance) {
    return new NaclSessionHandlerInstance(instance);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(NaclSessionHandlerModule);
};

}  // namespace session
}  // namespace mozc

namespace pp {

Module *CreateModule() {
  // We use dummy argc and argv to call InitGoogle().
  int argc = 1;
  char argv0[] = "NaclModule";
  char *argv_body[] = {argv0, NULL};
  char **argv = argv_body;
  InitGoogle(argv[0], &argc, &argv, true);

  return new mozc::session::NaclSessionHandlerModule();
}

}  // namespace pp
