// Copyright (C) 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "testdata_source.h"

#include <libaddressinput/callback.h>
#include <libaddressinput/source.h>

#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include <gtest/gtest.h>

#include "region_data_constants.h"

namespace {

using i18n::addressinput::BuildCallback;
using i18n::addressinput::kDataFileName;
using i18n::addressinput::RegionDataConstants;
using i18n::addressinput::Source;
using i18n::addressinput::TestdataSource;

// Tests for TestdataSource object.
class TestdataSourceTest : public testing::TestWithParam<std::string> {
 public:
  TestdataSourceTest(const TestdataSourceTest&) = delete;
  TestdataSourceTest& operator=(const TestdataSourceTest&) = delete;

 protected:
  TestdataSourceTest()
      : source_(false),
        source_with_path_(false, kDataFileName),
        aggregate_source_(true),
        aggregate_source_with_path_(true, kDataFileName),
        success_(false),
        key_(),
        data_(),
        data_ready_(BuildCallback(this, &TestdataSourceTest::OnDataReady)) {}

  TestdataSource source_;
  TestdataSource source_with_path_;
  TestdataSource aggregate_source_;
  TestdataSource aggregate_source_with_path_;
  bool success_;
  std::string key_;
  std::string data_;
  const std::unique_ptr<const Source::Callback> data_ready_;

 private:
  void OnDataReady(bool success, const std::string& key,
                   std::optional<std::string> data) {
    ASSERT_FALSE(success && !data.has_value());
    success_ = success;
    key_ = key;
    if (data.has_value()) {
      data_ = std::move(data).value();
    }
  }
};

// Returns testing::AssertionSuccess if |data| is valid callback data for
// |key|.
testing::AssertionResult DataIsValid(const std::string& data,
                                     const std::string& key) {
  if (data.empty()) {
    return testing::AssertionFailure() << "empty data";
  }

  std::string expected_data_begin = R"({"id":")" + key + R"(")";
  if (data.compare(0, expected_data_begin.length(), expected_data_begin) != 0) {
    return testing::AssertionFailure()
           << data << " does not begin with " << expected_data_begin;
  }

  // Verify that the data ends on "}.
  static const char kDataEnd[] = "\"}";
  static const size_t kDataEndLength = sizeof kDataEnd - 1;
  if (data.compare(data.length() - kDataEndLength,
                   kDataEndLength,
                   kDataEnd,
                   kDataEndLength) != 0) {
    return testing::AssertionFailure()
           << data << " does not end with " << kDataEnd;
  }

  return testing::AssertionSuccess();
}

// Verifies that TestdataSource gets valid data for a region code.
TEST_P(TestdataSourceTest, TestdataSourceHasValidDataForRegion) {
  std::string key = "data/" + GetParam();
  source_.Get(key, *data_ready_);

  EXPECT_TRUE(success_);
  EXPECT_EQ(key, key_);
  EXPECT_TRUE(DataIsValid(data_, key));
};

// Verifies that TestdataSource gets valid data for a region code.
TEST_P(TestdataSourceTest, TestdataSourceWithPathHasValidDataForRegion) {
  std::string key = "data/" + GetParam();
  source_with_path_.Get(key, *data_ready_);

  EXPECT_TRUE(success_);
  EXPECT_EQ(key, key_);
  EXPECT_TRUE(DataIsValid(data_, key));
};

// Returns testing::AssertionSuccess if |data| is valid aggregated callback
// data for |key|.
testing::AssertionResult AggregateDataIsValid(const std::string& data,
                                              const std::string& key) {
  if (data.empty()) {
    return testing::AssertionFailure() << "empty data";
  }

  std::string expected_data_begin = "{\"" + key;
  if (data.compare(0, expected_data_begin.length(), expected_data_begin) != 0) {
    return testing::AssertionFailure()
           << data << " does not begin with " << expected_data_begin;
  }

  // Verify that the data ends on "}}.
  static const char kDataEnd[] = "\"}}";
  static const size_t kDataEndLength = sizeof kDataEnd - 1;
  if (data.compare(data.length() - kDataEndLength,
                   kDataEndLength,
                   kDataEnd,
                   kDataEndLength) != 0) {
    return testing::AssertionFailure()
           << data << " does not end with " << kDataEnd;
  }

  return testing::AssertionSuccess();
}

// Verifies that TestdataSource gets valid aggregated data for a region code.
TEST_P(TestdataSourceTest, TestdataSourceHasValidAggregatedDataForRegion) {
  std::string key = "data/" + GetParam();
  aggregate_source_.Get(key, *data_ready_);

  EXPECT_TRUE(success_);
  EXPECT_EQ(key, key_);
  EXPECT_TRUE(AggregateDataIsValid(data_, key));
};

// Verifies that TestdataSource gets valid aggregated data for a region code.
TEST_P(TestdataSourceTest,
       TestdataSourceWithPathHasValidAggregatedDataForRegion) {
  std::string key = "data/" + GetParam();
  aggregate_source_with_path_.Get(key, *data_ready_);

  EXPECT_TRUE(success_);
  EXPECT_EQ(key, key_);
  EXPECT_TRUE(AggregateDataIsValid(data_, key));
};

// Test all region codes.
INSTANTIATE_TEST_SUITE_P(
    AllRegions, TestdataSourceTest,
    testing::ValuesIn(RegionDataConstants::GetRegionCodes()));

// Verifies that the key "data" also contains valid data.
TEST_F(TestdataSourceTest, GetExistingData) {
  static const std::string kKey = "data";
  source_.Get(kKey, *data_ready_);

  EXPECT_TRUE(success_);
  EXPECT_EQ(kKey, key_);
  EXPECT_TRUE(DataIsValid(data_, kKey));
}

// Verifies that requesting a missing key will return "{}".
TEST_F(TestdataSourceTest, GetMissingKeyReturnsEmptyDictionary) {
  static const std::string kJunkKey = "junk";
  source_.Get(kJunkKey, *data_ready_);

  EXPECT_TRUE(success_);
  EXPECT_EQ(kJunkKey, key_);
  EXPECT_EQ("{}", data_);
}

// Verifies that aggregate requesting of a missing key will also return "{}".
TEST_F(TestdataSourceTest, AggregateGetMissingKeyReturnsEmptyDictionary) {
  static const std::string kJunkKey = "junk";
  aggregate_source_.Get(kJunkKey, *data_ready_);

  EXPECT_TRUE(success_);
  EXPECT_EQ(kJunkKey, key_);
  EXPECT_EQ("{}", data_);
}

// Verifies that requesting an empty key will return "{}".
TEST_F(TestdataSourceTest, GetEmptyKeyReturnsEmptyDictionary) {
  static const std::string kEmptyKey;
  source_.Get(kEmptyKey, *data_ready_);

  EXPECT_TRUE(success_);
  EXPECT_EQ(kEmptyKey, key_);
  EXPECT_EQ("{}", data_);
}

}  // namespace
