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

#include "base/logging.h"
#include "base/port.h"
#include "converter/connector.h"
#include "converter/converter.h"
#include "converter/converter_interface.h"
#include "converter/immutable_converter.h"
#include "converter/immutable_converter_interface.h"
#include "converter/segmenter.h"
#include "data_manager/data_manager_interface.h"
#include "dictionary/dictionary_impl.h"
#include "dictionary/dictionary_interface.h"
#include "dictionary/pos_group.h"
#include "dictionary/pos_matcher.h"
#include "dictionary/suffix_dictionary.h"
#include "dictionary/suffix_dictionary_token.h"
#include "dictionary/suppression_dictionary.h"
#include "dictionary/system/system_dictionary.h"
#include "dictionary/system/value_dictionary.h"
#include "dictionary/user_dictionary.h"
#include "engine/engine_interface.h"
#include "engine/user_data_manager_interface.h"
#include "prediction/dictionary_predictor.h"
#include "prediction/predictor.h"
#include "prediction/predictor_interface.h"
#include "prediction/suggestion_filter.h"
#include "prediction/user_history_predictor.h"
#include "rewriter/rewriter.h"
#include "rewriter/rewriter_interface.h"

using mozc::dictionary::DictionaryImpl;
using mozc::dictionary::PosGroup;
using mozc::dictionary::SuffixDictionary;
using mozc::dictionary::SuffixToken;
using mozc::dictionary::SuppressionDictionary;
using mozc::dictionary::SystemDictionary;
using mozc::dictionary::UserDictionary;
using mozc::dictionary::UserPOS;
using mozc::dictionary::ValueDictionary;

namespace mozc {
namespace {

class UserDataManagerImpl : public UserDataManagerInterface {
 public:
  explicit UserDataManagerImpl(PredictorInterface *predictor,
                               RewriterInterface *rewriter)
      : predictor_(predictor), rewriter_(rewriter) {}
  ~UserDataManagerImpl();

  virtual bool Sync();
  virtual bool Reload();
  virtual bool ClearUserHistory();
  virtual bool ClearUserPrediction();
  virtual bool ClearUnusedUserPrediction();
  virtual bool ClearUserPredictionEntry(const string &key, const string &value);
  virtual bool WaitForSyncerForTest();

 private:
  PredictorInterface *predictor_;
  RewriterInterface *rewriter_;

  DISALLOW_COPY_AND_ASSIGN(UserDataManagerImpl);
};

UserDataManagerImpl::~UserDataManagerImpl() {}

bool UserDataManagerImpl::Sync() {
  // TODO(noriyukit): In the current implementation, if rewriter_->Sync() fails,
  // predictor_->Sync() is never called. Check if we should call
  // predictor_->Sync() or not.
  return rewriter_->Sync() && predictor_->Sync();
}

bool UserDataManagerImpl::Reload() {
  // TODO(noriyukit): The same TODO as Sync().
  return rewriter_->Reload() && predictor_->Reload();
}

bool UserDataManagerImpl::ClearUserHistory() {
  rewriter_->Clear();
  return true;
}

bool UserDataManagerImpl::ClearUserPrediction() {
  predictor_->ClearAllHistory();
  return true;
}

bool UserDataManagerImpl::ClearUnusedUserPrediction() {
  predictor_->ClearUnusedHistory();
  return true;
}

bool UserDataManagerImpl::ClearUserPredictionEntry(const string &key,
                                                   const string &value) {
  return predictor_->ClearHistoryEntry(key, value);
}

bool UserDataManagerImpl::WaitForSyncerForTest() {
  return predictor_->WaitForSyncerForTest();
}

}  // namespace

Engine::Engine() {}
Engine::~Engine() {}

// Since the composite predictor class differs on desktop and mobile, Init()
// takes a function pointer to create an instance of predictor class.
void Engine::Init(
    const DataManagerInterface *data_manager,
    PredictorInterface *(*predictor_factory)(PredictorInterface *,
                                             PredictorInterface *),
    bool enable_content_word_learning) {
  CHECK(data_manager);
  CHECK(predictor_factory);

  suppression_dictionary_.reset(new SuppressionDictionary);
  CHECK(suppression_dictionary_.get());

  user_dictionary_.reset(
      new UserDictionary(new UserPOS(data_manager->GetUserPOSData()),
                         data_manager->GetPOSMatcher(),
                         suppression_dictionary_.get()));
  CHECK(user_dictionary_.get());

  const char *dictionary_data = NULL;
  int dictionary_size = 0;
  data_manager->GetSystemDictionaryData(&dictionary_data, &dictionary_size);

  dictionary_.reset(new DictionaryImpl(
      SystemDictionary::Builder(dictionary_data, dictionary_size).Build(),
      ValueDictionary::CreateValueDictionaryFromImage(
          *data_manager->GetPOSMatcher(), dictionary_data, dictionary_size),
      user_dictionary_.get(),
      suppression_dictionary_.get(),
      data_manager->GetPOSMatcher()));
  CHECK(dictionary_.get());

  const SuffixToken *suffix_tokens = NULL;
  size_t suffix_tokens_size = 0;
  data_manager->GetSuffixDictionaryData(&suffix_tokens, &suffix_tokens_size);
  suffix_dictionary_.reset(new SuffixDictionary(suffix_tokens,
                                                suffix_tokens_size));
  CHECK(suffix_dictionary_.get());

  connector_.reset(Connector::CreateFromDataManager(*data_manager));
  CHECK(connector_.get());

  segmenter_.reset(Segmenter::CreateFromDataManager(*data_manager));
  CHECK(segmenter_.get());

  pos_group_.reset(new PosGroup(data_manager->GetPosGroupData()));
  CHECK(pos_group_.get());

  {
    const char *data = NULL;
    size_t size = 0;
    data_manager->GetSuggestionFilterData(&data, &size);
    CHECK(data);
    suggestion_filter_.reset(new SuggestionFilter(data, size));
  }

  immutable_converter_.reset(new ImmutableConverterImpl(
      dictionary_.get(),
      suffix_dictionary_.get(),
      suppression_dictionary_.get(),
      connector_.get(),
      segmenter_.get(),
      data_manager->GetPOSMatcher(),
      pos_group_.get(),
      suggestion_filter_.get()));
  CHECK(immutable_converter_.get());

  // Since predictor and rewriter require a pointer to a converter instace,
  // allocate it first without initialization. It is initialized at the end of
  // this method.
  // TODO(noriyukit): This circular dependency is a bad design as careful
  // handling is necessary to avoid infinite loop. Find more beautiful design
  // and fix it!
  ConverterImpl *converter_impl = new ConverterImpl;
  converter_.reset(converter_impl);  // Involves cast to ConverterInterface*.
  CHECK(converter_.get());

  {
    // Create a predictor with three sub-predictors, dictionary predictor, user
    // history predictor, and extra predictor.
    PredictorInterface *dictionary_predictor =
        new DictionaryPredictor(converter_.get(),
                                immutable_converter_.get(),
                                dictionary_.get(),
                                suffix_dictionary_.get(),
                                connector_.get(),
                                segmenter_.get(),
                                data_manager->GetPOSMatcher(),
                                suggestion_filter_.get());
    CHECK(dictionary_predictor);

    PredictorInterface *user_history_predictor =
        new UserHistoryPredictor(dictionary_.get(),
                                 data_manager->GetPOSMatcher(),
                                 suppression_dictionary_.get(),
                                 enable_content_word_learning);
    CHECK(user_history_predictor);

    predictor_ = (*predictor_factory)(dictionary_predictor,
                                      user_history_predictor);
    CHECK(predictor_);
  }

  rewriter_ = new RewriterImpl(converter_impl,
                               data_manager,
                               pos_group_.get(),
                               dictionary_.get());
  CHECK(rewriter_);

  converter_impl->Init(data_manager->GetPOSMatcher(),
                       suppression_dictionary_.get(),
                       predictor_,
                       rewriter_,
                       immutable_converter_.get());

  user_data_manager_.reset(new UserDataManagerImpl(predictor_, rewriter_));
}

bool Engine::Reload() {
  if (!user_dictionary_.get()) {
    return true;
  }
  VLOG(1) << "Reloading user dictionary";
  return user_dictionary_->Reload();
}

}  // namespace mozc
