// 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 "data_manager/packed/packed_data_manager.h"

#include <memory>

#include "base/logging.h"
#include "base/mmap.h"
#include "base/protobuf/coded_stream.h"
#include "base/protobuf/gzip_stream.h"
#include "base/protobuf/zero_copy_stream_impl.h"
#include "converter/boundary_struct.h"
#include "data_manager/data_manager_interface.h"
#include "data_manager/packed/system_dictionary_data.pb.h"
#include "data_manager/packed/system_dictionary_format_version.h"
#include "dictionary/pos_matcher.h"
#include "dictionary/suffix_dictionary_token.h"
#include "rewriter/correction_rewriter.h"
#include "rewriter/counter_suffix.h"
#include "rewriter/embedded_dictionary.h"
#ifndef NO_USAGE_REWRITER
#include "rewriter/usage_rewriter_data_structs.h"
#endif  // NO_USAGE_REWRITER

DEFINE_string(dataset,
              "",
              "The dataset tag of the POS data.");

using std::unique_ptr;
using mozc::dictionary::SuffixToken;

namespace mozc {
namespace packed {
namespace {
// Default value of the total bytes limit defined in protobuf library is 64MB.
// Our big dictionary size is about 50MB. So we don't need to change it.
const size_t kDefaultTotalBytesLimit = 64 << 20;

class PackedPOSMatcher : public POSMatcher {
 public:
  PackedPOSMatcher(const uint16 *const rule_id_table,
                   const Range *const *const range_table)
      : POSMatcher(rule_id_table, range_table) {
  }
};

unique_ptr<PackedDataManager> g_data_manager;

}  // namespace

class PackedDataManager::Impl {
 public:
  Impl();
  ~Impl();
  bool Init(const string &system_dictionary_data);
  bool InitWithZippedData(const string &zipped_system_dictionary_data);
  string GetDictionaryVersion();

  const UserPOS::POSToken *GetUserPOSData() const;
  const POSMatcher *GetPOSMatcher() const;
  const uint8 *GetPosGroupData() const;
  void GetConnectorData(const char **data, size_t *size) const;
  void GetSegmenterData(
      size_t *l_num_elements, size_t *r_num_elements,
      const uint16 **l_table, const uint16 **r_table,
      size_t *bitarray_num_bytes, const char **bitarray_data,
      const BoundaryData **boundary_data) const;
  void GetSystemDictionaryData(const char **data, int *size) const;
  void GetSuffixDictionaryData(const SuffixToken **data,
                               size_t *size) const;
  void GetReadingCorrectionData(const ReadingCorrectionItem **array,
                                size_t *size) const;
  void GetCollocationData(const char **array, size_t *size) const;
  void GetCollocationSuppressionData(const char **array,
                                     size_t *size) const;
  void GetSuggestionFilterData(const char **data, size_t *size) const;
  void GetSymbolRewriterData(const EmbeddedDictionary::Token **data,
                             size_t *size) const;
#ifndef NO_USAGE_REWRITER
  void GetUsageRewriterData(
      const ConjugationSuffix **base_conjugation_suffix,
      const ConjugationSuffix **conjugation_suffix_data,
      const int **conjugation_suffix_data_index,
      const UsageDictItem **usage_data_value) const;
#endif  // NO_USAGE_REWRITER
  const uint16 *GetRuleIdTableForTest() const;
  const void *GetRangeTablesForTest() const;
  void GetCounterSuffixSortedArray(const CounterSuffixEntry **array,
                                   size_t *size) const;

 private:
  // Non-const struct of POSMatcher::Range
  struct Range {
    uint16 lower;
    uint16 upper;
  };
  bool InitializeWithSystemDictionaryData();

  unique_ptr<UserPOS::POSToken[]> pos_token_;
  unique_ptr<UserPOS::ConjugationType[]> conjugation_array_;
  unique_ptr<uint16[]> rule_id_table_;
  unique_ptr<POSMatcher::Range *[]> range_tables_;
  unique_ptr<Range[]> range_table_items_;
  unique_ptr<BoundaryData[]> boundary_data_;
  unique_ptr<SuffixToken[]> suffix_tokens_;
  unique_ptr<ReadingCorrectionItem[]> reading_corrections_;
  size_t compressed_l_size_;
  size_t compressed_r_size_;
  unique_ptr<uint16[]> compressed_lid_table_;
  unique_ptr<uint16[]> compressed_rid_table_;
  unique_ptr<EmbeddedDictionary::Value[]> symbol_data_values_;
  size_t symbol_data_token_size_;
  unique_ptr<EmbeddedDictionary::Token[]> symbol_data_tokens_;
  unique_ptr<POSMatcher> pos_matcher_;
  unique_ptr<SystemDictionaryData> system_dictionary_data_;
#ifndef NO_USAGE_REWRITER
  unique_ptr<ConjugationSuffix[]> base_conjugation_suffix_;
  unique_ptr<ConjugationSuffix[]> conjugation_suffix_data_;
  unique_ptr<int[]> conjugation_suffix_data_index_;
  unique_ptr<UsageDictItem[]> usage_data_value_;
#endif  // NO_USAGE_REWRITER
  unique_ptr<CounterSuffixEntry[]> counter_suffix_data_;
};

PackedDataManager::Impl::Impl()
    : compressed_l_size_(0),
      compressed_r_size_(0),
      symbol_data_token_size_(0) {
}

PackedDataManager::Impl::~Impl() {
}

bool PackedDataManager::Impl::Init(const string &system_dictionary_data) {
  system_dictionary_data_.reset(new SystemDictionaryData);
  if (!system_dictionary_data_->ParseFromString(system_dictionary_data)) {
    LOG(ERROR) << "System dictionary data protobuf format error!";
    return false;
  }
  return InitializeWithSystemDictionaryData();
}

bool PackedDataManager::Impl::InitWithZippedData(
    const string &zipped_system_dictionary_data) {
  protobuf::io::ArrayInputStream input(zipped_system_dictionary_data.data(),
                                       zipped_system_dictionary_data.size());
  protobuf::io::GzipInputStream gzip_stream(&input);
  protobuf::io::CodedInputStream coded_stream(&gzip_stream);
  // Disables the total bytes warning.
  coded_stream.SetTotalBytesLimit(kDefaultTotalBytesLimit, -1);
  system_dictionary_data_.reset(new SystemDictionaryData);
  if (!system_dictionary_data_->ParseFromCodedStream(&coded_stream)) {
    LOG(ERROR) << "System dictionary data protobuf format error!";
    return false;
  }
  return InitializeWithSystemDictionaryData();
}

string PackedDataManager::Impl::GetDictionaryVersion() {
  return system_dictionary_data_->product_version();
}

bool PackedDataManager::Impl::InitializeWithSystemDictionaryData() {
  // Checks format version.
  if (system_dictionary_data_->format_version() !=
          kSystemDictionaryFormatVersion) {
    LOG(ERROR) << "System dictionary data format version miss match! "
               << " expected:" << kSystemDictionaryFormatVersion
               << " actual:" << system_dictionary_data_->format_version();
    return false;
  }
  // Makes UserPOS data.
  pos_token_.reset(
      new UserPOS::POSToken[system_dictionary_data_->pos_tokens_size()]);
  size_t conjugation_count = 0;
  for (size_t i = 0; i < system_dictionary_data_->pos_tokens_size(); ++i) {
    conjugation_count +=
        system_dictionary_data_->pos_tokens(i).conjugation_forms_size();
  }
  conjugation_array_.reset(new UserPOS::ConjugationType[conjugation_count]);
  size_t conjugation_index = 0;
  for (size_t i = 0; i < system_dictionary_data_->pos_tokens_size(); ++i) {
    const SystemDictionaryData::PosToken &pos_token =
        system_dictionary_data_->pos_tokens(i);
    if (pos_token.has_pos()) {
      pos_token_[i].pos = pos_token.pos().data();
    } else {
      pos_token_[i].pos = NULL;
    }
    pos_token_[i].conjugation_size =
        pos_token.conjugation_forms_size();
    pos_token_[i].conjugation_form = &conjugation_array_[conjugation_index];
    if (pos_token.conjugation_forms_size() == 0) {
      pos_token_[i].conjugation_form = NULL;
    }
    for (size_t j = 0; j < pos_token.conjugation_forms_size(); ++j) {
      const SystemDictionaryData::PosToken::ConjugationType &conjugation_form =
          pos_token.conjugation_forms(j);
      if (conjugation_form.has_key_suffix()) {
        conjugation_array_[conjugation_index].key_suffix =
            conjugation_form.key_suffix().data();
      } else {
        conjugation_array_[conjugation_index].key_suffix = NULL;
      }
      if (conjugation_form.has_value_suffix()) {
        conjugation_array_[conjugation_index].value_suffix =
            conjugation_form.value_suffix().data();
      } else {
        conjugation_array_[conjugation_index].value_suffix = NULL;
      }
      conjugation_array_[conjugation_index].id = conjugation_form.id();
      ++conjugation_index;
    }
  }

  // Makes POSMatcher data.
  rule_id_table_.reset(
      new uint16[
          system_dictionary_data_->pos_matcher_data().rule_id_table_size()]);
  for (size_t i = 0;
       i < system_dictionary_data_->pos_matcher_data().rule_id_table_size();
       ++i) {
    rule_id_table_[i] =
        system_dictionary_data_->pos_matcher_data().rule_id_table(i);
  }
  const SystemDictionaryData::PosMatcherData &pos_matcher_data =
      system_dictionary_data_->pos_matcher_data();
  range_tables_.reset(
      new POSMatcher::Range*[pos_matcher_data.range_tables_size()]);
  size_t range_count = 0;
  for (size_t i = 0; i < pos_matcher_data.range_tables_size(); ++i) {
    range_count += pos_matcher_data.range_tables(i).ranges_size();
  }
  range_table_items_.reset(
      new Range[range_count + pos_matcher_data.range_tables_size()]);
  size_t range_index = 0;
  for (size_t i = 0; i < pos_matcher_data.range_tables_size(); ++i) {
    const SystemDictionaryData::PosMatcherData::RangeTable &table =
        pos_matcher_data.range_tables(i);
    range_tables_[i] =
        reinterpret_cast<POSMatcher::Range *>(&range_table_items_[range_index]);
    for (size_t j = 0; j < table.ranges_size(); ++j) {
      const SystemDictionaryData::PosMatcherData::RangeTable::Range &range =
          table.ranges(j);
      range_table_items_[range_index].lower = range.lower();
      range_table_items_[range_index].upper = range.upper();
      ++range_index;
    }
    range_table_items_[range_index].lower = static_cast<uint16>(0xFFFF);
    range_table_items_[range_index].upper = static_cast<uint16>(0xFFFF);
    ++range_index;
  }

  // Makes boundary data.
  boundary_data_.reset(
      new BoundaryData[system_dictionary_data_->boundary_data_size()]);
  for (size_t i = 0; i < system_dictionary_data_->boundary_data_size(); ++i) {
    const SystemDictionaryData::BoundaryData &boundary_data =
        system_dictionary_data_->boundary_data(i);
    boundary_data_[i].prefix_penalty = boundary_data.prefix_penalty();
    boundary_data_[i].suffix_penalty = boundary_data.suffix_penalty();
  }

  // Makes suffix data.
  suffix_tokens_.reset(
      new SuffixToken[system_dictionary_data_->suffix_tokens_size()]);
  for (size_t i = 0;
       i < system_dictionary_data_->suffix_tokens_size();
       ++i) {
    const SystemDictionaryData::SuffixToken &suffix_token =
        system_dictionary_data_->suffix_tokens(i);
    if (suffix_token.has_key()) {
      suffix_tokens_[i].key = suffix_token.key().data();
    } else {
      suffix_tokens_[i].key = NULL;
    }
    if (suffix_token.has_value()) {
      suffix_tokens_[i].value = suffix_token.value().data();
    } else {
      suffix_tokens_[i].value = NULL;
    }
    suffix_tokens_[i].lid = suffix_token.lid();
    suffix_tokens_[i].rid = suffix_token.rid();
    suffix_tokens_[i].wcost = suffix_token.wcost();
  }

  // Makes reading correction data.
  reading_corrections_.reset(
      new ReadingCorrectionItem[
          system_dictionary_data_->reading_corrections_size()]);
  for (size_t i = 0;
       i < system_dictionary_data_->reading_corrections_size();
       ++i) {
    const SystemDictionaryData::ReadingCorrectionItem &item =
        system_dictionary_data_->reading_corrections(i);
    if (item.has_value()) {
      reading_corrections_[i].value = item.value().data();
    } else {
      reading_corrections_[i].value = NULL;
    }
    if (item.has_error()) {
      reading_corrections_[i].error = item.error().data();
    } else {
      reading_corrections_[i].error = NULL;
    }
    if (item.has_correction()) {
      reading_corrections_[i].correction = item.correction().data();
    } else {
      reading_corrections_[i].correction = NULL;
    }
  }

  // Makes segment data.
  const SystemDictionaryData::SegmenterData &segmenter_data =
      system_dictionary_data_->segmenter_data();
  compressed_l_size_ = segmenter_data.compressed_l_size();
  compressed_r_size_ = segmenter_data.compressed_r_size();
  compressed_lid_table_.reset(
      new uint16[segmenter_data.compressed_lid_table_size()]);
  for (size_t i = 0; i < segmenter_data.compressed_lid_table_size(); ++i) {
    compressed_lid_table_[i] = segmenter_data.compressed_lid_table(i);
  }
  compressed_rid_table_.reset(
      new uint16[segmenter_data.compressed_rid_table_size()]);
  for (size_t i = 0; i < segmenter_data.compressed_rid_table_size(); ++i) {
    compressed_rid_table_[i] = segmenter_data.compressed_rid_table(i);
  }

  // Makes symbol dictionary data.
  const SystemDictionaryData::EmbeddedDictionary &symbol_dictionary =
      system_dictionary_data_->symbol_dictionary();
  size_t symbol_value_count = 0;
  for (size_t i = 0; i < symbol_dictionary.tokens_size(); ++i) {
    symbol_value_count += symbol_dictionary.tokens(i).values_size();
  }
  symbol_data_values_.reset(
      new EmbeddedDictionary::Value[symbol_value_count + 1]);
  symbol_data_token_size_ = symbol_dictionary.tokens_size();
  symbol_data_tokens_.reset(
    new EmbeddedDictionary::Token[symbol_data_token_size_ + 1]);
  EmbeddedDictionary::Value *value_ptr = symbol_data_values_.get();
  EmbeddedDictionary::Token *token_ptr = symbol_data_tokens_.get();
  for (size_t i = 0; i < symbol_dictionary.tokens_size(); ++i) {
    const SystemDictionaryData::EmbeddedDictionary::Token &token =
        symbol_dictionary.tokens(i);
    token_ptr->key = token.key().data();
    token_ptr->value = value_ptr;
    token_ptr->value_size = token.values_size();
    ++token_ptr;
    for (size_t j = 0; j < token.values_size(); ++j) {
      const SystemDictionaryData::EmbeddedDictionary::Value &value =
          token.values(j);
      if (value.has_value()) {
        value_ptr->value = value.value().data();
      } else {
        value_ptr->value = NULL;
      }
      if (value.has_description()) {
        value_ptr->description = value.description().data();
      } else {
        value_ptr->description = NULL;
      }
      if (value.has_additional_description()) {
        value_ptr->additional_description =
            value.additional_description().data();
      } else {
        value_ptr->additional_description = NULL;
      }
      value_ptr->lid = value.lid();
      value_ptr->rid = value.rid();
      value_ptr->cost = value.cost();
      ++value_ptr;
    }
  }
  value_ptr->value = NULL;
  value_ptr->description = NULL;
  value_ptr->additional_description = NULL;
  value_ptr->lid = 0;
  value_ptr->rid = 0;
  value_ptr->cost = 0;
  token_ptr->key = NULL;
  token_ptr->value = symbol_data_values_.get();
  token_ptr->value_size = symbol_value_count;

  // Makes POSMatcher.
  pos_matcher_.reset(
      new PackedPOSMatcher(rule_id_table_.get(), range_tables_.get()));

#ifndef NO_USAGE_REWRITER
  // Makes Usge rewriter data.
  const SystemDictionaryData::UsageRewriterData &usage_rewriter_data =
      system_dictionary_data_->usage_rewriter_data();
  const size_t conjugation_num = usage_rewriter_data.conjugations_size();
  base_conjugation_suffix_.reset(new ConjugationSuffix[conjugation_num]);
  conjugation_suffix_data_index_.reset(new int[conjugation_num + 1]);

  size_t suffix_data_num = 0;
  conjugation_suffix_data_index_[0] = 0;
  for (size_t i = 0; i < conjugation_num; ++i) {
    const SystemDictionaryData::UsageRewriterData::Conjugation &conjugation =
      usage_rewriter_data.conjugations(i);
    base_conjugation_suffix_[i].value_suffix =
        conjugation.base_suffix().value_suffix().data();
    base_conjugation_suffix_[i].key_suffix =
        conjugation.base_suffix().key_suffix().data();
    suffix_data_num +=
        usage_rewriter_data.conjugations(i).conjugation_suffixes_size();
    conjugation_suffix_data_index_[i + 1] = suffix_data_num;
  }
  conjugation_suffix_data_.reset(new ConjugationSuffix[suffix_data_num]);
  size_t conjugation_suffix_id = 0;
  for (size_t i = 0; i < conjugation_num; ++i) {
    const SystemDictionaryData::UsageRewriterData::Conjugation &conjugation =
      usage_rewriter_data.conjugations(i);
    for (size_t j = 0; j < conjugation.conjugation_suffixes_size(); ++j) {
      conjugation_suffix_data_[conjugation_suffix_id].value_suffix =
        conjugation.conjugation_suffixes(j).value_suffix().data();
      conjugation_suffix_data_[conjugation_suffix_id].key_suffix =
        conjugation.conjugation_suffixes(j).key_suffix().data();
      ++conjugation_suffix_id;
    }
  }

  usage_data_value_.reset(
      new UsageDictItem[usage_rewriter_data.usage_data_values_size() + 1]);
  for (size_t i = 0; i < usage_rewriter_data.usage_data_values_size(); ++i) {
    const SystemDictionaryData::UsageRewriterData::UsageDictItem &item =
        usage_rewriter_data.usage_data_values(i);
    usage_data_value_[i].id = item.id();
    usage_data_value_[i].key = item.key().data();
    usage_data_value_[i].value = item.value().data();
    usage_data_value_[i].conjugation_id = item.conjugation_id();
    usage_data_value_[i].meaning = item.meaning().data();
  }
  UsageDictItem *last_item =
      &usage_data_value_[usage_rewriter_data.usage_data_values_size()];
  last_item->id = 0;
  last_item->key = NULL;
  last_item->value = NULL;
  last_item->conjugation_id = 0;
  last_item->meaning = NULL;
#endif  // NO_USAGE_REWRITER

  // Makes counter suffix sorted array.
  {
    const size_t size =
        system_dictionary_data_->counter_suffix_data_size();
    if (size > 0) {
      counter_suffix_data_.reset(new CounterSuffixEntry[size]);
      for (size_t i = 0; i < size; ++i) {
        counter_suffix_data_[i].suffix =
            system_dictionary_data_->counter_suffix_data(i).data();
        counter_suffix_data_[i].size =
            system_dictionary_data_->counter_suffix_data(i).size();
      }
    }
  }
  return true;
}

const UserPOS::POSToken *PackedDataManager::Impl::GetUserPOSData() const {
  return pos_token_.get();
}

const POSMatcher *PackedDataManager::Impl::GetPOSMatcher() const {
  return pos_matcher_.get();
}

const uint8 *PackedDataManager::Impl::GetPosGroupData() const {
  return reinterpret_cast<const uint8 *>(
      system_dictionary_data_->lid_group_data().data());
}

void PackedDataManager::Impl::GetConnectorData(
    const char **data,
    size_t *size) const {
  *data = system_dictionary_data_->connection_data().data();
  *size = system_dictionary_data_->connection_data().size();
}

void PackedDataManager::Impl::GetSegmenterData(
    size_t *l_num_elements, size_t *r_num_elements,
    const uint16 **l_table, const uint16 **r_table,
    size_t *bitarray_num_bytes, const char **bitarray_data,
    const BoundaryData **boundary_data) const {
  *l_num_elements = compressed_l_size_;
  *r_num_elements = compressed_r_size_;
  *l_table = compressed_lid_table_.get();
  *r_table = compressed_rid_table_.get();
  *bitarray_num_bytes =
      system_dictionary_data_->segmenter_data().bit_array_data().size();
  *bitarray_data =
      system_dictionary_data_->segmenter_data().bit_array_data().data();
  *boundary_data = boundary_data_.get();
}

void PackedDataManager::Impl::GetSystemDictionaryData(
    const char **data,
    int *size) const {
  *data = system_dictionary_data_->dictionary_data().data();
  *size = system_dictionary_data_->dictionary_data().size();
}

void PackedDataManager::Impl::GetSuffixDictionaryData(
    const SuffixToken **data,
    size_t *size) const {
  *data = suffix_tokens_.get();
  *size = system_dictionary_data_->suffix_tokens().size();
}

void PackedDataManager::Impl::GetReadingCorrectionData(
    const ReadingCorrectionItem **array,
    size_t *size) const {
  *array = reading_corrections_.get();
  *size = system_dictionary_data_->reading_corrections().size();
}

void PackedDataManager::Impl::GetCollocationData(
  const char **array,
  size_t *size) const {
  *array = system_dictionary_data_->collocation_data().data();
  *size = system_dictionary_data_->collocation_data().size();
}

void PackedDataManager::Impl::GetCollocationSuppressionData(
    const char **array,
    size_t *size) const {
  *array = system_dictionary_data_->collocation_suppression_data().data();
  *size = system_dictionary_data_->collocation_suppression_data().size();
}

void PackedDataManager::Impl::GetSuggestionFilterData(
    const char **data,
    size_t *size) const {
  *data = system_dictionary_data_->suggestion_filter_data().data();
  *size = system_dictionary_data_->suggestion_filter_data().size();
}

void PackedDataManager::Impl::GetSymbolRewriterData(
    const EmbeddedDictionary::Token **data,
    size_t *size) const {
  *data = symbol_data_tokens_.get();
  *size = symbol_data_token_size_;
}

#ifndef NO_USAGE_REWRITER
void PackedDataManager::Impl::GetUsageRewriterData(
    const ConjugationSuffix **base_conjugation_suffix,
    const ConjugationSuffix **conjugation_suffix_data,
    const int **conjugation_suffix_data_index,
    const UsageDictItem **usage_data_value) const {
  *base_conjugation_suffix = base_conjugation_suffix_.get();
  *conjugation_suffix_data = conjugation_suffix_data_.get();
  *conjugation_suffix_data_index = conjugation_suffix_data_index_.get();
  *usage_data_value = usage_data_value_.get();
}
#endif  // NO_USAGE_REWRITER

const uint16 *PackedDataManager::Impl::GetRuleIdTableForTest() const {
  return rule_id_table_.get();
}

const void *PackedDataManager::Impl::GetRangeTablesForTest() const {
  return range_tables_.get();
}

void PackedDataManager::Impl::GetCounterSuffixSortedArray(
    const CounterSuffixEntry **array, size_t *size) const {
  *array = counter_suffix_data_.get();
  *size = system_dictionary_data_->counter_suffix_data_size();
}


PackedDataManager::PackedDataManager() {
}

PackedDataManager::~PackedDataManager() {
}

bool PackedDataManager::Init(const string &system_dictionary_data) {
  manager_impl_.reset(new Impl());
  if (manager_impl_->Init(system_dictionary_data)) {
    return true;
  }
  LOG(ERROR) << "PackedDataManager initialization error";
  manager_impl_.reset();
  return false;
}

bool PackedDataManager::InitWithZippedData(
    const string &zipped_system_dictionary_data) {
  manager_impl_.reset(new Impl());
  if (manager_impl_->InitWithZippedData(zipped_system_dictionary_data)) {
    return true;
  }
  LOG(ERROR) << "PackedDataManager initialization error";
  manager_impl_.reset();
  return false;
}

string PackedDataManager::GetDictionaryVersion() {
  return manager_impl_->GetDictionaryVersion();
}

const UserPOS::POSToken *PackedDataManager::GetUserPOSData() const {
  return manager_impl_->GetUserPOSData();
}

PackedDataManager *PackedDataManager::GetUserPosManager() {
  if (!g_data_manager.get()) {
    LOG(INFO) << "PackedDataManager::GetUserPosManager null!";
    LOG(INFO) << "FLAGS_dataset: [" << FLAGS_dataset << "]";
    if (FLAGS_dataset.empty()) {
      LOG(FATAL) << "PackedDataManager::GetUserPosManager ERROR!";
    } else {
      unique_ptr<PackedDataManager> data_manager(new PackedDataManager);
      string buffer;
      {
        Mmap mmap;
        CHECK(mmap.Open(FLAGS_dataset.c_str(), "r"));
        buffer.assign(mmap.begin(), mmap.size());
      }
      if (data_manager->Init(buffer)) {
        RegisterPackedDataManager(data_manager.release());
      }
    }
  }
  CHECK(g_data_manager.get()) << "PackedDataManager::GetUserPosManager ERROR!";
  return g_data_manager.get();
}

const POSMatcher *PackedDataManager::GetPOSMatcher() const {
  return manager_impl_->GetPOSMatcher();
}

const uint8 *PackedDataManager::GetPosGroupData() const {
  return manager_impl_->GetPosGroupData();
}

void PackedDataManager::GetConnectorData(
    const char **data,
    size_t *size) const {
  manager_impl_->GetConnectorData(data, size);
}

void PackedDataManager::GetSegmenterData(
    size_t *l_num_elements, size_t *r_num_elements,
    const uint16 **l_table, const uint16 **r_table,
    size_t *bitarray_num_bytes, const char **bitarray_data,
    const BoundaryData **boundary_data) const {
  manager_impl_->GetSegmenterData(l_num_elements,
                                  r_num_elements,
                                  l_table,
                                  r_table,
                                  bitarray_num_bytes,
                                  bitarray_data,
                                  boundary_data);
}

void PackedDataManager::GetSystemDictionaryData(
    const char **data,
    int *size) const {
  manager_impl_->GetSystemDictionaryData(data, size);
}

void PackedDataManager::GetSuffixDictionaryData(
    const SuffixToken **data,
    size_t *size) const {
  manager_impl_->GetSuffixDictionaryData(data, size);
}

void PackedDataManager::GetReadingCorrectionData(
    const ReadingCorrectionItem **array,
    size_t *size) const {
  manager_impl_->GetReadingCorrectionData(array, size);
}

void PackedDataManager::GetCollocationData(
  const char **array,
  size_t *size) const {
  manager_impl_->GetCollocationData(array, size);
}

void PackedDataManager::GetCollocationSuppressionData(
    const char **array,
    size_t *size) const {
  manager_impl_->GetCollocationSuppressionData(array, size);
}

void PackedDataManager::GetSuggestionFilterData(
    const char **data,
    size_t *size) const {
  manager_impl_->GetSuggestionFilterData(data, size);
}

void PackedDataManager::GetSymbolRewriterData(
    const EmbeddedDictionary::Token **data,
    size_t *size) const {
  manager_impl_->GetSymbolRewriterData(data, size);
}

#ifndef NO_USAGE_REWRITER
void PackedDataManager::GetUsageRewriterData(
    const ConjugationSuffix **base_conjugation_suffix,
    const ConjugationSuffix **conjugation_suffix_data,
    const int **conjugation_suffix_data_index,
    const UsageDictItem **usage_data_value) const {
  manager_impl_->GetUsageRewriterData(base_conjugation_suffix,
                                      conjugation_suffix_data,
                                      conjugation_suffix_data_index,
                                      usage_data_value);
}
#endif  // NO_USAGE_REWRITER

void PackedDataManager::GetCounterSuffixSortedArray(
    const CounterSuffixEntry **array, size_t *size) const {
  manager_impl_->GetCounterSuffixSortedArray(array, size);
}

const uint16 *PackedDataManager::GetRuleIdTableForTest() const {
  return manager_impl_->GetRuleIdTableForTest();
}

const void *PackedDataManager::GetRangeTablesForTest() const {
  return manager_impl_->GetRangeTablesForTest();
}

void RegisterPackedDataManager(PackedDataManager *packed_data_manager) {
  g_data_manager.reset(packed_data_manager);
}

PackedDataManager *GetPackedDataManager() {
  return g_data_manager.get();
}

}  // namespace packed
}  // namespace mozc
