// Copyright 2017 The Fuchsia Authors
//
// 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.

#ifndef COBALT_ANALYZER_STORE_DATA_STORE_TEST_H_
#define COBALT_ANALYZER_STORE_DATA_STORE_TEST_H_

#include "analyzer/store/data_store.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "gflags/gflags.h"
#include "glog/logging.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"

// This file contains type-parameterized tests of the DataStore interface.
//
// We use C++ templates along with the macros TYPED_TEST_CASE_P and
// TYPED_TEST_P in order to define test templates that may be instantiated to
// to produce concrete tests of various implementations of the DataStore
// interface.
//
// See memory_store_test.cc and bigtable_store_emulator_test.cc for the
// concrete instantiations.
//
// NOTE: If you add a new test to this file you must add its name to the
// invocation REGISTER_TYPED_TEST_CASE_P macro at the bottom of this file.

namespace cobalt {
namespace analyzer {
namespace store {

static const int kNumColumns = 3;

// DataStoreTest is templatized on the parameter |StoreFactoryClass| which
// must be the name of a class that contains the following method:
//   static DataStore* NewStore()
// See MemoryStoreFactory in memory_store_test_helper.h for example.
//
// Note: For simplicity we perform all tests using the Observations table
// only.
template <class StoreFactoryClass>
class DataStoreTest : public ::testing::Test {
 protected:
  DataStoreTest() : data_store_(StoreFactoryClass::NewStore()) {}

  void SetUp() {
    EXPECT_EQ(kOK, data_store_->DeleteAllRows(DataStore::kObservations));
    EXPECT_EQ(0u, GetNumRows());
  }

  // Adds |num_rows| rows with kNumColumns columns each.
  void AddRows(int num_rows);

  // Returns the total number of rows in the store.
  size_t GetNumRows();

  // Reads the specified number of columns from the specified row and checks
  // that the result is as expected.
  //
  // If num_columns = 0 then no columns are specified in the read and therefore
  // all columns should be returned and so the expected num_columns is
  // kNumColumns.
  void ReadSingleRowAndCheck(int num_columns, int row_idnex,
                             bool expect_row_found);

  // Reads the specified number of columns from the specified row range
  // and checks that the results are as expected.
  //
  // If num_columns = 0 then no columns are specified in the read and therefore
  // all columns should be returned and so the expected num_columns is
  // kNumColumns.
  //
  // Set limit_row = -1 to indicate an unbounded range.
  void ReadRowsAndCheck(int num_columns, int start_row, bool inclusive,
                        int limit_row, int max_rows, size_t expected_num_rows,
                        bool expect_more_available);

  void DeleteRowsWithPrefix(int basis, int suffix_length);

  // In order to work around the following bug in the Bigtable Emulator
  // https://github.com/GoogleCloudPlatform/google-cloud-go/issues/489
  // we use a different set of row keys for each test. Each row created during
  // a test will be prefixed with |test_prefix|.
  void set_test_prefix(std::string test_prefix) {
    test_prefix_ = std::move(test_prefix);
  }

  // Generates a row key string based on the given |index| and prefix.
  static std::string RowKeyString(const std::string& prefix, uint32_t index) {
    // We allocate a buffer of size 14 to leave room for the trailing null.
    std::string out(14, 0);
    std::snprintf(&out[0], out.size(), "row%.10u", index);
    // Discard the trailing null.
    out.resize(13);
    return prefix + out;
  }

  // Generates a column name string based on the given |colum_index|.
  static std::string ColumnNameString(uint32_t column_index) {
    std::string out(17, 0);
    std::snprintf(&out[0], out.size(), "column%.10u", column_index);
    return out;
  }

  // Generates a value string based on the given |row_index| and |colum_index|.
  static std::string ValueString(uint32_t row_index, uint32_t column_index) {
    std::string out(27, 0);
    std::snprintf(&out[0], out.size(), "value%.10u:%.10u", row_index,
                  column_index);
    return out;
  }

  // Makes a vector of column name strings for |num_columns| columns.
  static std::vector<std::string> MakeColumnNames(size_t num_columns) {
    std::vector<std::string> column_names;
    for (size_t column_index = 0; column_index < num_columns; column_index++) {
      column_names.push_back(ColumnNameString(column_index));
    }
    return column_names;
  }

  std::unique_ptr<DataStore> data_store_;
  std::string test_prefix_;
};

template <class StoreFactoryClass>
void DataStoreTest<StoreFactoryClass>::AddRows(int num_rows) {
  std::vector<std::string> column_names = MakeColumnNames(kNumColumns);
  std::vector<DataStore::Row> rows;
  for (int row_index = 0; row_index < num_rows; row_index++) {
    DataStore::Row row;
    row.key = RowKeyString(test_prefix_, row_index);
    for (int column_index = 0; column_index < kNumColumns; column_index++) {
      row.column_values[column_names[column_index]] =
          ValueString(row_index, column_index);
    }
    rows.emplace_back(std::move(row));
  }
  EXPECT_EQ(kOK,
            data_store_->WriteRows(DataStore::kObservations, std::move(rows)));
}

template <class StoreFactoryClass>
size_t DataStoreTest<StoreFactoryClass>::GetNumRows() {
  std::vector<std::string> column_names;

  DataStore::ReadResponse read_response = data_store_->ReadRows(
      DataStore::kObservations, RowKeyString(test_prefix_, 0), true, "",
      column_names, UINT32_MAX);

  EXPECT_EQ(kOK, read_response.status);
  return read_response.rows.size();
}

template <class StoreFactoryClass>
void DataStoreTest<StoreFactoryClass>::ReadSingleRowAndCheck(
    int num_columns, int row_index, bool expect_row_found) {
  std::vector<std::string> column_names = MakeColumnNames(num_columns);
  DataStore::Row row;
  row.key = RowKeyString(test_prefix_, row_index);
  auto status =
      data_store_->ReadRow(DataStore::kObservations, column_names, &row);
  if (expect_row_found) {
    ASSERT_EQ(kOK, status);
  } else {
    EXPECT_EQ(kNotFound, status);
    return;
  }
  int expected_num_columns = (num_columns == 0 ? kNumColumns : num_columns);
  for (int column_index = 0; column_index < expected_num_columns;
       column_index++) {
    EXPECT_EQ(ValueString(row_index, column_index),
              row.column_values.at(ColumnNameString(column_index)));
  }
}

template <class StoreFactoryClass>
void DataStoreTest<StoreFactoryClass>::ReadRowsAndCheck(
    int num_columns, int start_row, bool inclusive, int limit_row, int max_rows,
    size_t expected_num_rows, bool expect_more_available) {
  std::vector<std::string> column_names = MakeColumnNames(num_columns);

  std::string limit_row_key;
  if (limit_row < 0) {
    limit_row_key = "";
  } else {
    limit_row_key = RowKeyString(test_prefix_, limit_row);
  }
  DataStore::ReadResponse read_response = data_store_->ReadRows(
      DataStore::kObservations, RowKeyString(test_prefix_, start_row),
      inclusive, limit_row_key, column_names, max_rows);

  EXPECT_EQ(kOK, read_response.status);
  EXPECT_EQ(expected_num_rows, read_response.rows.size());
  size_t expected_num_columns = (num_columns == 0 ? kNumColumns : num_columns);
  int row_index = (inclusive ? start_row : start_row + 1);
  for (const DataStore::Row& row : read_response.rows) {
    EXPECT_EQ(RowKeyString(test_prefix_, row_index), row.key);
    EXPECT_EQ(expected_num_columns, row.column_values.size());
    for (size_t column_index = 0; column_index < expected_num_columns;
         column_index++) {
      EXPECT_EQ(ValueString(row_index, column_index),
                row.column_values.at(ColumnNameString(column_index)));
    }
    row_index++;
  }
  EXPECT_EQ(expect_more_available, read_response.more_available);
}

template <class StoreFactoryClass>
void DataStoreTest<StoreFactoryClass>::DeleteRowsWithPrefix(int basis,
                                                            int suffix_length) {
  std::string prefix = RowKeyString(test_prefix_, basis);
  prefix.resize(prefix.size() - suffix_length);
  Status status =
      data_store_->DeleteRowsWithPrefix(DataStore::kObservations, prefix);

  EXPECT_EQ(kOK, status);
}

TYPED_TEST_CASE_P(DataStoreTest);

TYPED_TEST_P(DataStoreTest, WriteAndReadRows) {
  // Add 3000 rows of 3 columns each.
  this->AddRows(3000);

  // Read row number 0, expect it to exist.
  this->ReadSingleRowAndCheck(kNumColumns, 0, true);

  // Read row number 1234, expect it to exist.
  this->ReadSingleRowAndCheck(kNumColumns, 1234, true);

  // Read row number 2999, expect it to exist.
  this->ReadSingleRowAndCheck(kNumColumns, 2999, true);

  // Read row number 3000, expect it to not exist.
  this->ReadSingleRowAndCheck(kNumColumns, 3000, false);

  // Read rows [100, 175) with max_rows = 50. Expect 50 rows with more
  // available.
  size_t max_rows = 50;
  size_t expected_rows = 50;
  this->ReadRowsAndCheck(kNumColumns, 100, true, 175, max_rows, expected_rows,
                         true);

  // Read rows (100, 175) with max_rows = 50. Expect 50 rows with more
  // available.
  this->ReadRowsAndCheck(kNumColumns, 100, false, 175, max_rows, expected_rows,
                         true);

  // Read rows [100, 175) with max_rows = 80. Expect 75 rows with no more
  // available.
  max_rows = 80;
  expected_rows = 75;
  this->ReadRowsAndCheck(kNumColumns, 100, true, 175, max_rows, expected_rows,
                         false);

  // Read rows (100, 175) with max_rows = 80. Expect 74 rows with no more
  // available.
  max_rows = 80;
  expected_rows = 74;
  this->ReadRowsAndCheck(kNumColumns, 100, false, 175, max_rows, expected_rows,
                         false);

  // Read rows [100, 2100) with max_rows = 100. Expect 100 rows with
  // more  available.
  max_rows = 100;
  expected_rows = 100;
  this->ReadRowsAndCheck(kNumColumns, 100, true, 2100, max_rows, expected_rows,
                         true);

  // Read rows (100, 2100) with max_rows = 100. Expect 100 rows with
  // more  available.
  this->ReadRowsAndCheck(kNumColumns, 100, false, 2100, max_rows, expected_rows,
                         true);

  // Read rows (100, 2100) with max_rows = UINT32_MAX. Expect 1999 rows with
  // no more  available.
  max_rows = UINT32_MAX;
  expected_rows = 1999;
  this->ReadRowsAndCheck(kNumColumns, 100, false, 2100, max_rows, expected_rows,
                         false);

  // Read rows [0, 1) with max_rows = 100. Expect 1 row with
  // more no available.
  max_rows = 100;
  expected_rows = 1;
  this->ReadRowsAndCheck(kNumColumns, 0, true, 1, max_rows, expected_rows,
                         false);
}

// Tests reading an unbounded range.
TYPED_TEST_P(DataStoreTest, UnboundedRange) {
  this->set_test_prefix("UnboundedRange");
  // Add 1000 rows of 3 columns each.
  this->AddRows(1000);
  ASSERT_EQ(1000u, this->GetNumRows());

  // Read rows [100, infinity) with max_rows = 50. Expect 50 rows with more
  // available.
  size_t max_rows = 50;
  size_t expected_rows = 50;
  this->ReadRowsAndCheck(kNumColumns, 100, true, -1, max_rows, expected_rows,
                         true);

  // Read rows (100, infinity) with max_rows = 50. Expect 50 rows with more
  // available.
  this->ReadRowsAndCheck(kNumColumns, 100, false, -1, max_rows, expected_rows,
                         true);

  // Read rows [100, infinity) with max_rows = 100. Expect 100 rows with
  // more  available.
  max_rows = 100;
  expected_rows = 100;
  this->ReadRowsAndCheck(kNumColumns, 100, true, -1, max_rows, expected_rows,
                         true);

  // Read rows (100, infinity) with max_rows = 100. Expect 100 rows with
  // more  available.
  this->ReadRowsAndCheck(kNumColumns, 100, false, -1, max_rows, expected_rows,
                         true);

  // Read rows [950, infinity) with max_rows = 100. Expect 50 rows with
  // no more  available.
  expected_rows = 50;
  this->ReadRowsAndCheck(kNumColumns, 950, true, -1, max_rows, expected_rows,
                         false);

  // Read rows (950, infinity) with max_rows = 100 Expect 49 rows with
  // no more  available.
  expected_rows = 49;
  this->ReadRowsAndCheck(kNumColumns, 950, false, -1, max_rows, expected_rows,
                         false);

  // Read rows [0, infinity) with max_rows = 10,000. Expect 1,000 rows with
  // no more  available.
  max_rows = 10000;
  expected_rows = 1000;
  this->ReadRowsAndCheck(kNumColumns, 0, true, -1, max_rows, expected_rows,
                         false);

  // Read rows [0, infinity) with max_rows = 1,000, Expect 1,000 rows with
  // no more  available.
  max_rows = 1000;
  expected_rows = 1000;
  this->ReadRowsAndCheck(kNumColumns, 0, true, -1, max_rows, expected_rows,
                         false);

  // Read rows [0, infinity) with max_rows = 999, Expect 999 rows with
  // more  available.
  max_rows = 999;
  expected_rows = 999;
  this->ReadRowsAndCheck(kNumColumns, 0, true, -1, max_rows, expected_rows,
                         true);
}

TYPED_TEST_P(DataStoreTest, ReadDifferentNumColumns) {
  this->set_test_prefix("ReadDifferentNumColumns");
  // Add 10 rows of 3 columns each.
  this->AddRows(10);
  ASSERT_EQ(10u, this->GetNumRows());

  // Read rows [3, 6). Expect 3 rows with no more available.
  size_t max_rows = UINT32_MAX;
  size_t expected_rows = 3;

  // Try the read with different numbers of columns specified to read.
  for (size_t num_columns = 0; num_columns <= kNumColumns; num_columns++) {
    this->ReadRowsAndCheck(num_columns, 3, true, 6, max_rows, expected_rows,
                           false);
  }

  // Read row 8 alone.
  // Try the read with different numbers of columns specified to read.
  for (size_t num_columns = 0; num_columns <= kNumColumns; num_columns++) {
    this->ReadSingleRowAndCheck(num_columns, 8, true);
  }
}

// Tests deleting ranges of rows.
TYPED_TEST_P(DataStoreTest, DeleteRanges) {
  this->set_test_prefix("DeleteRanges");
  // Initially there should be no rows.
  ASSERT_EQ(0u, this->GetNumRows());

  // Add 3000 rows.
  this->AddRows(3000);
  // Now there should be 3000 rows.
  ASSERT_EQ(3000u, this->GetNumRows());

  // Delete 10^0 rows starting with row 100.
  // i.e. delete row 100
  this->DeleteRowsWithPrefix(100, 0);
  ASSERT_EQ(2999u, this->GetNumRows());

  // Delete 10^1 rows starting with row 200.
  // i.e. delete rows [200, 209]
  this->DeleteRowsWithPrefix(200, 1);
  ASSERT_EQ(2989u, this->GetNumRows());

  // Delete 10^2 rows starting with row 300.
  // i.e. delete rows [300, 399]
  this->DeleteRowsWithPrefix(300, 2);
  ASSERT_EQ(2889u, this->GetNumRows());

  // Delete 10^3 rows starting with row 0.
  // i.e. delete rows [0, 999]
  this->DeleteRowsWithPrefix(0, 3);
  ASSERT_EQ(2000u, this->GetNumRows());

  // Delete 10^3 rows starting with row 1000.
  // i.e. delete rows [1000, 1999]
  this->DeleteRowsWithPrefix(1000, 3);
  ASSERT_EQ(1000u, this->GetNumRows());

  // Delete 10^4 rows starting with row 0.
  // i.e. delete rows [0, 9999]
  this->DeleteRowsWithPrefix(0, 4);
  ASSERT_EQ(0u, this->GetNumRows());
}

REGISTER_TYPED_TEST_CASE_P(DataStoreTest, WriteAndReadRows, UnboundedRange,
                           ReadDifferentNumColumns, DeleteRanges);

}  // namespace store
}  // namespace analyzer
}  // namespace cobalt

#endif  // COBALT_ANALYZER_STORE_DATA_STORE_TEST_H_
