// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ml/text_suggestions.h"

#include <string>

#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/native_library.h>

namespace ml {
namespace {

constexpr char kTextSuggesterFilesPath[] =
    "/opt/google/chrome/ml_models/suggest/";
constexpr char kTextSuggesterLibraryRelativePath[] = "libsuggest.so";
constexpr char kTextSuggesterModelRelativePath[] = "nwp.uint8.mmap.tflite";
constexpr char kTextSuggesterSymbolsRelativePath[] = "nwp.csym";

}  // namespace

TextSuggestions::TextSuggestions()
    : status_(Status::kUninitialized),
      create_text_suggester_(nullptr),
      load_text_suggester_(nullptr),
      suggest_candidates_(nullptr),
      delete_suggest_candidates_result_data_(nullptr),
      destroy_text_suggester_(nullptr) {
  if (!IsTextSuggestionsSupported()) {
    status_ = Status::kNotSupported;
    return;
  }

  base::NativeLibraryOptions native_library_options;
  native_library_options.prefer_own_symbols = true;
  base::NativeLibraryLoadError error;
  library_.emplace(base::LoadNativeLibraryWithOptions(
      base::FilePath(kTextSuggesterFilesPath)
          .Append(kTextSuggesterLibraryRelativePath),
      native_library_options, &error));
  if (!library_->is_valid()) {
    status_ = Status::kLoadLibraryFailed;
    LOG(ERROR) << error.ToString();
    return;
  }

#define ML_TEXT_SUGGESTER_LOOKUP_FUNCTION(function_ptr, name)          \
  function_ptr =                                                       \
      reinterpret_cast<name##Fn>(library_->GetFunctionPointer(#name)); \
  if (function_ptr == NULL) {                                          \
    status_ = Status::kFunctionLookupFailed;                           \
    return;                                                            \
  }
  // Lookup the function pointers
  ML_TEXT_SUGGESTER_LOOKUP_FUNCTION(create_text_suggester_,
                                    CreateTextSuggester);
  ML_TEXT_SUGGESTER_LOOKUP_FUNCTION(load_text_suggester_, LoadTextSuggester);
  ML_TEXT_SUGGESTER_LOOKUP_FUNCTION(suggest_candidates_, SuggestCandidates);
  ML_TEXT_SUGGESTER_LOOKUP_FUNCTION(delete_suggest_candidates_result_data_,
                                    DeleteSuggestCandidatesResultData);
  ML_TEXT_SUGGESTER_LOOKUP_FUNCTION(destroy_text_suggester_,
                                    DestroyTextSuggester);
#undef ML_TEXT_SUGGESTER_LOOKUP_FUNCTION

  status_ = Status::kOk;
}

TextSuggestions::~TextSuggestions() = default;

TextSuggestions* TextSuggestions::GetInstance() {
  static base::NoDestructor<TextSuggestions> instance;
  return instance.get();
}

TextSuggestions::Status TextSuggestions::GetStatus() const {
  return status_;
}

TextSuggester TextSuggestions::CreateTextSuggester() const {
  DCHECK(status_ == Status::kOk);
  return (*create_text_suggester_)();
}

bool TextSuggestions::LoadTextSuggester(TextSuggester const suggester) const {
  DCHECK(status_ == Status::kOk);
  chrome_knowledge::TextSuggesterSettings settings;
  settings.set_multi_word_model_path(
      base::FilePath(kTextSuggesterFilesPath)
          .Append(kTextSuggesterModelRelativePath)
          .value());
  settings.set_multi_word_syms_path(
      base::FilePath(kTextSuggesterFilesPath)
          .Append(kTextSuggesterSymbolsRelativePath)
          .value());
  const std::string settings_pb = settings.SerializeAsString();
  return (*load_text_suggester_)(suggester, settings_pb.data(),
                                 settings_pb.size());
}

bool TextSuggestions::GenerateSuggestions(
    TextSuggester const suggester,
    const chrome_knowledge::TextSuggesterRequest& request,
    chrome_knowledge::TextSuggesterResult* const result) const {
  DCHECK(status_ == Status::kOk);
  const std::string request_pb = request.SerializeAsString();
  char* result_data = nullptr;
  int result_size = 0;
  const bool suggestions_generated =
      (*suggest_candidates_)(suggester, request_pb.data(), request_pb.size(),
                             &result_data, &result_size);
  if (suggestions_generated) {
    const bool parse_result_status =
        result->ParseFromArray(result_data, result_size);
    DCHECK(parse_result_status);
    // only need to delete result_data if succeeds.
    (*delete_suggest_candidates_result_data_)(result_data);
  }

  return suggestions_generated;
}

void TextSuggestions::DestroyTextSuggester(
    TextSuggester const suggester) const {
  DCHECK(status_ == Status::kOk);
  (*destroy_text_suggester_)(suggester);
}

}  // namespace ml
