// Unit test for sandboxed_hunspell

#include <optional>
#include <string>

#include "devtools/build/runtime/get_runfiles_dir.h"
#include "file/base/filelineiter.h"
#include "file/base/path.h"
#include "testing/base/public/benchmark.h"
#include "testing/base/public/gmock.h"
#include "testing/base/public/gunit.h"
#include "third_party/absl/log/check.h"
#include "third_party/absl/log/log.h"
#include "third_party/absl/status/status.h"
#include "third_party/absl/strings/string_view.h"
#include "third_party/hunspell/sandbox/sandbox.h"
#include "third_party/hunspell/sandbox/sandboxed_hunspell.sapi.h"
#include "third_party/hunspell/src/hunspell/hunspell.h"
#include "third_party/sandboxed_api/util/status_matchers.h"
#include "third_party/sandboxed_api/vars.h"

namespace {

static constexpr absl::string_view test_dir_ =
    "/tests";

static constexpr absl::string_view kAffixFileName = "utf8.aff";
static constexpr absl::string_view kDictionaryFileName = "utf8.dic";

static constexpr absl::string_view kGoodFileName = "utf8.good";
static constexpr absl::string_view kWrongFileName = "utf8_nonbmp.wrong";

static constexpr absl::string_view kSuggestion = "fo";
static constexpr absl::string_view kRandomWord = "random_word123";

std::string GetTestFilePath(const absl::string_view& filename) {
  return file::JoinPath(devtools_build::GetDataDependencyFilepath(test_dir_),
                        filename);
}

class HunspellTest : public ::testing::Test {
 public:
  HunspellTest()
      : s_affix_filename_(GetTestFilePath(kAffixFileName)),
        s_dictionary_filename_(GetTestFilePath(kDictionaryFileName)),
        sandbox_(s_affix_filename_, s_dictionary_filename_),
        api_(&sandbox_) {
    sapi::v::ConstCStr c_affix_filename(s_affix_filename_.c_str());
    sapi::v::ConstCStr c_dictionary_filename(s_dictionary_filename_.c_str());

    CHECK(sandbox_.Init().ok());
    absl::StatusOr<sandboxed_hunspell::Hunhandle*> hunspell =
        api_.Hunspell_create(c_affix_filename.PtrBefore(),
                             c_dictionary_filename.PtrBefore());
    CHECK(hunspell.ok());

    hunspellrp_.emplace(*hunspell);
  }

  ~HunspellTest() override {
    if (hunspellrp_) {
      absl::Status status = api_.Hunspell_destroy(&(*hunspellrp_));
      CHECK(status.ok());
    }
  }

 protected:
  const std::string s_affix_filename_;
  const std::string s_dictionary_filename_;
  sandboxed_hunspell::LibHunspellSapiSandbox sandbox_;
  sandboxed_hunspell::LibHunspellApi api_;
  std::optional<sapi::v::RemotePtr> hunspellrp_;
};

TEST_F(HunspellTest, CheckEncoding) {
  SAPI_ASSERT_OK_AND_ASSIGN(char* ret,
                            api_.Hunspell_get_dic_encoding(&(*hunspellrp_)));
  SAPI_ASSERT_OK_AND_ASSIGN(std::string encoding, api_.GetSandbox()->GetCString(
                                                      sapi::v::RemotePtr(ret)));
  EXPECT_EQ(encoding, "UTF-8");
}

TEST_F(HunspellTest, CheckGoodSpell) {
  SAPI_ASSERT_OK_AND_ASSIGN(char* _,
                            api_.Hunspell_get_dic_encoding(&(*hunspellrp_)));

  for (std::string& buf :
       FileLines(GetTestFilePath(kGoodFileName), FileLineIterator::NO_LF)) {
    sapi::v::ConstCStr cbuf(buf.c_str());
    SAPI_ASSERT_OK_AND_ASSIGN(
        int result, api_.Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
    ASSERT_EQ(result, 1);
  }
}

TEST_F(HunspellTest, CheckWrongSpell) {
  SAPI_ASSERT_OK_AND_ASSIGN(char* _,
                            api_.Hunspell_get_dic_encoding(&(*hunspellrp_)));

  for (std::string& buf :
       FileLines(GetTestFilePath(kWrongFileName), FileLineIterator::NO_LF)) {
    sapi::v::ConstCStr cbuf(buf.c_str());
    SAPI_ASSERT_OK_AND_ASSIGN(
        int result, api_.Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
    ASSERT_EQ(result, 0);
  }
}

TEST_F(HunspellTest, CheckAddToDict) {
  sapi::v::ConstCStr cbuf(kRandomWord.data());

  int result;
  SAPI_ASSERT_OK_AND_ASSIGN(
      result, api_.Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
  ASSERT_EQ(result, 0);

  SAPI_ASSERT_OK_AND_ASSIGN(
      result, api_.Hunspell_add(&(*hunspellrp_), cbuf.PtrBefore()));
  ASSERT_EQ(result, 0);

  SAPI_ASSERT_OK_AND_ASSIGN(
      result, api_.Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
  ASSERT_EQ(result, 1);

  SAPI_ASSERT_OK_AND_ASSIGN(
      result, api_.Hunspell_remove(&(*hunspellrp_), cbuf.PtrBefore()));
  ASSERT_EQ(result, 0);

  SAPI_ASSERT_OK_AND_ASSIGN(
      result, api_.Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
  ASSERT_EQ(result, 0);
}

TEST_F(HunspellTest, CheckSuggestion) {
  sapi::v::ConstCStr cbuf(kSuggestion.data());

  SAPI_ASSERT_OK_AND_ASSIGN(
      int result, api_.Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
  ASSERT_EQ(result, 0);

  sapi::v::GenericPtr outptr;
  SAPI_ASSERT_OK_AND_ASSIGN(
      int nlist, api_.Hunspell_suggest(&(*hunspellrp_), outptr.PtrAfter(),
                                       cbuf.PtrBefore()));
  ASSERT_GT(nlist, 0);
}

// The following go/benchmark tests allow viewing the performance overhead
// the sandboxed API causes. Due to the nature of SAPI sandboxes, the only
// reliable metric is `time/op`.
// Please note that every SAPI sandbox cold start takes ~10ms.
//
// benchy --perflab --runs 20 -benchtime 0.5s \
//         //third_party/hunspell/sandbox:sandboxed_hunspell_test
//
// name                             time/op
// BM_Sandboxed_hunspell_spell      228µs ± 2%
// BM_Unsandboxed_hunspell_spell    133µs ± 5%

void BM_Sandboxed_hunspell_spell(benchmark::State& state) {
  std::string suggestion = "fo";
  std::string s_affix_filename = GetTestFilePath("utf8.aff");
  std::string s_dictionary_filename = GetTestFilePath("utf8.dic");
  sandboxed_hunspell::LibHunspellSapiSandbox sandbox(s_affix_filename,
                                                     s_dictionary_filename);

  ASSERT_OK(sandbox.Init());
  sandboxed_hunspell::LibHunspellApi api(&sandbox);

  sapi::v::ConstCStr c_affix_filename(s_affix_filename.c_str());
  sapi::v::ConstCStr c_dictionary_filename(s_dictionary_filename.c_str());
  sapi::v::ConstCStr cbuf(suggestion.c_str());

  for (const auto _ : state) {
    SAPI_ASSERT_OK_AND_ASSIGN(
        sandboxed_hunspell::Hunhandle * hunspell,
        api.Hunspell_create(c_affix_filename.PtrBefore(),
                            c_dictionary_filename.PtrBefore()));

    sapi::v::RemotePtr hunspellrp(hunspell);

    SAPI_ASSERT_OK_AND_ASSIGN(
        int result, api.Hunspell_spell(&hunspellrp, cbuf.PtrBefore()));
    ASSERT_EQ(result, 0);

    absl::Status status = api.Hunspell_destroy(&hunspellrp);
    ASSERT_THAT(status, sapi::IsOk());
  }
}

void BM_Unsandboxed_hunspell_spell(benchmark::State& state) {
  std::string suggestion = "fo";
  for (const auto _ : state) {
    Hunhandle* hunspell = Hunspell_create(GetTestFilePath("utf8.aff").c_str(),
                                          GetTestFilePath("utf8.dic").c_str());
    ASSERT_EQ(Hunspell_spell(hunspell, suggestion.c_str()), 0);
    Hunspell_destroy(hunspell);
  }
}

BENCHMARK(BM_Sandboxed_hunspell_spell);
BENCHMARK(BM_Unsandboxed_hunspell_spell);

}  // namespace
