// This program checks spelling and suggests corrections for misspelled words.
//
// This example illustrates the use of the sandboxed_hunspell library with an
// affix file (definitions for the dictionary) and a dictionary file to check
// the contents of the WORDS_TO_CHECK file.

#include <unistd.h>

#include <cstdlib>
#include <string>

#include "base/init_google.h"
#include "file/base/filelineiter.h"
#include "third_party/absl/flags/flag.h"
#include "third_party/absl/log/flags.h"
#include "third_party/absl/log/log.h"
#include "third_party/absl/status/status.h"
#include "third_party/absl/status/statusor.h"
#include "third_party/hunspell/sandbox/sandbox.h"
#include "third_party/hunspell/sandbox/sandboxed_hunspell.sapi.h"
#include "third_party/sandboxed_api/util/status_macros.h"
#include "third_party/sandboxed_api/var_array.h"
#include "third_party/sandboxed_api/var_int.h"
#include "third_party/sandboxed_api/var_ptr.h"

ABSL_FLAG(std::string, affix_file, "", "File path to affix file.");
ABSL_FLAG(std::string, dict_file, "", "File path to dictionarie file.");
ABSL_FLAG(std::string, in_file, "", "File path to file to check.");

absl::Status PrintSuggest(sandboxed_hunspell::LibHunspellApi& api,
                          sapi::v::RemotePtr& hunspellrp,
                          sapi::v::ConstCStr& word) {
  sapi::v::GenericPtr outptr;

  SAPI_ASSIGN_OR_RETURN(
      int nlist,
      api.Hunspell_suggest(&hunspellrp, outptr.PtrAfter(), word.PtrBefore()));

  if (nlist == 0) {
    LOG(INFO) << "No suggestions.";
    return absl::OkStatus();
  }

  sapi::v::Array<char*> suggestion_listp(nlist);
  suggestion_listp.SetRemote(reinterpret_cast<void*>(outptr.GetValue()));
  SAPI_RETURN_IF_ERROR(
      api.GetSandbox()->TransferFromSandboxee(&suggestion_listp));

  LOG(INFO) << "Suggestions:";
  for (int i = 0; i < nlist; ++i) {
    sapi::v::RemotePtr sugrp(suggestion_listp[i]);
    SAPI_ASSIGN_OR_RETURN(std::string sugestion,
                          api.GetSandbox()->GetCString(sugrp));
    LOG(INFO) << sugestion;
  }

  return api.Hunspell_free_list(&hunspellrp, outptr.PtrNone(), nlist);
}

int main(int argc, char* argv[]) {
  InitGoogle(argv[0], &argc, &argv, /*remove_flags=*/true);

  // Always log to stderr
  absl::SetFlag(&FLAGS_logtostderr, true);

  if (absl::GetFlag(FLAGS_affix_file).empty() ||
      absl::GetFlag(FLAGS_dict_file).empty()) {
    LOG(ERROR) << "--" << absl::GetFlagReflectionHandle(FLAGS_affix_file).Name()
               << ", --"
               << absl::GetFlagReflectionHandle(FLAGS_dict_file).Name()
               << ", and --"
               << absl::GetFlagReflectionHandle(FLAGS_in_file).Name()
               << " are required";
    return EXIT_FAILURE;
  }

  std::string affix_file = absl::GetFlag(FLAGS_affix_file);
  std::string dict_file = absl::GetFlag(FLAGS_dict_file);
  sapi::v::ConstCStr c_affix_file(affix_file.c_str());
  sapi::v::ConstCStr c_dictionary_file(dict_file.c_str());

  sandboxed_hunspell::LibHunspellSapiSandbox sandbox(affix_file, dict_file);
  if (!sandbox.Init().ok()) {
    LOG(ERROR) << "Unable to start sandbox";
    return EXIT_FAILURE;
  }

  sandboxed_hunspell::LibHunspellApi api(&sandbox);
  absl::StatusOr<sandboxed_hunspell::Hunhandle*> hunspell = api.Hunspell_create(
      c_affix_file.PtrBefore(), c_dictionary_file.PtrBefore());
  if (!hunspell.ok()) {
    LOG(ERROR) << "Could not initialize hunsepll";
    return EXIT_FAILURE;
  }

  sapi::v::RemotePtr hunspellrp(*hunspell);
  for (std::string& buf :
       FileLines(absl::GetFlag(FLAGS_in_file), FileLineIterator::NO_LF)) {
    sapi::v::ConstCStr cbuf(buf.c_str());
    absl::StatusOr<int> result =
        api.Hunspell_spell(&hunspellrp, cbuf.PtrBefore());
    if (!result.ok()) {
      LOG(ERROR) << "Could not check word" << result.status();
      return EXIT_FAILURE;
    }

    if (*result) {
      LOG(INFO) << "Word " << buf << " is ok";
      continue;
    }
    LOG(INFO) << "Word " << buf << " is incorrect";
    absl::Status status = PrintSuggest(api, hunspellrp, cbuf);
    if (!status.ok()) {
      LOG(ERROR) << "Unable to get all suggestion" << status;
      return EXIT_FAILURE;
    }
  }

  if (!api.Hunspell_destroy(&hunspellrp).ok()) {
    LOG(ERROR) << "Unable to destroy hunspell";
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
