// 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_H_
#define COBALT_ANALYZER_STORE_DATA_STORE_H_

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

#include "grpc++/grpc++.h"

namespace cobalt {
namespace analyzer {
namespace store {

// The status of an operation.
enum Status {
  // The operation succeeded.
  kOK = 0,

  // The operation was not attempted because the arguments are invalid.
  kInvalidArguments,

  // The requested item was not found.
  kNotFound,

  // The item being created already exists.
  kAlreadyExists,

  // The operation requires a pre-condition which is not true.
  kPreconditionFailed,

  // The operation was attempted but failed for an unspecified reason. More
  // information may be found in the log file.
  kOperationFailed
};

// Interface to the Cobalt underlying data store. Instead of working
// directly with this interface, work with ObservationStore and
// ReportStore which are implemented on top of this interface.
//
// The Cobalt data store is a key-multi-value store. There are
// two tables: Observations and Reports. Each table is organized into
// rows identified by a unique string row key. Each row has multiple values
// organized into columns. Each column has a string name and a string value.
// Different rows may have different numbers of columns and different column
// names.
//
// The rows are ordered lexicographically by row_key.
class DataStore {
 public:
  static std::unique_ptr<DataStore> CreateFromFlagsOrDie();

  // The different tables that are controlled by this data store.
  enum Table {
    // The Observations table holds the Observations received from the Shuffler.
    kObservations,

    // The ReportMetadata table holds metadata about reports.
    kReportMetadata,

    // The ReportRows table holds the actual rows of reports.
    kReportRows,
  };

  virtual ~DataStore() = 0;

  // A row of the data store. A move-only type.
  struct Row {
    // Default constructor
    Row() {}

    // Move constructor
    Row(Row&& other)
        : key(std::move(other.key)),
          column_values(std::move(other.column_values)) {}

    // The row key
    std::string key;

    // The column values. The keys of the map are the column names and the
    // values of the map are the column values.
    std::map<std::string, std::string> column_values;
  };

  // Writes a row of |table|. The operation may be an insert of a new row
  // or a replacement of an existing row.
  //
  // Returns kOK on success or an error status on failure.
  virtual Status WriteRow(Table table, Row row) = 0;

  // Writes many rows of |table|. The operation may consists of inserts of
  // new rows and replacements of existing rows.
  //
  // The sum over all of the rows of the number of columns being written
  // must be less than 100,000.
  //
  // Returns kOK on success or an error status on failure.
  virtual Status WriteRows(Table table, std::vector<Row> rows) = 0;

  // Reads the row with the given key from the store, if there is one.
  //
  // table: Which table to read from.
  //
  // column_names: If non-empty then the read will only return data from the
  //     columns with the specified names. Otherwise there will be no
  //     restriction.
  //
  // row: is both input and output. On input only the |key| field will be
  //     inspected and the |column_values| will be cleared. The row with the
  //     given |key| will be fetched from the datastore.
  //
  // Returns kOK on success, kNotFound if there is no such row,
  // kInvalidArgument if |row| is nullptr, and kOperationFailed if there was
  // any other unexpected problem.
  virtual Status ReadRow(Table table,
                         const std::vector<std::string>& column_names,
                         Row* row) = 0;

  // A ReadResponse is returned from the ReadRows() method.
  struct ReadResponse {
    // status will be kOK on success or an error status on failure.
    // If there was an error then the other fields of ReadResponse
    // should be ignored.
    Status status;

    // The grpc::Status returned from Bigtable.
    grpc::Status grpc_status;

    // If status is kOK then this is the list of returned rows. If
    // |more_available| is true then there will be at least one row.
    std::vector<Row> rows;

    // If status is kOK, indicates whether or not there were more rows available
    // from the requested range than were returned. If true the caller may
    // invoke ReadRows again, passing as |start_row_key| the key of the last
    // returned row from |rows| and passing |inclusive| = false. Note that it
    // is possible that more_available = true even if rows.size() < max_rows.
    // In other words fewer than max_rows might be returned even if there are
    // more rows available. However if |more_availabe| is true then it
    // is guaranteed that |rows| will not be empty.
    bool more_available = false;
  };

  // Reads a lexicographic range of rows from the store.
  //
  // table: Which table to read from.
  //
  // start_row_key: The start of the lexicographic interval to be read.
  //
  // inclusive: Whether or not the interval to be read includes the
  //    |start_row_key|.
  //
  // limit_row_key: The *exclusive* end of the interval to be read. That is,
  //     the interval does not include |limit_row_key|. If |limit_row_key| is
  //     empty it is interpreted as the infinite row key. |start_row_key| must
  //     be less than |limit_row_key| lexicographically.
  //
  // column_names: If non-empty then the read will only return data from the
  //     columns with the specified names. Otherwise there will be no
  //     restriction.
  //
  // max_rows: At most |max_rows| rows will be returned. The number of
  //     returned rows may be less than max_rows for several reasons.
  //     Must be positive or kInvalidArguments will be returned.
  virtual ReadResponse ReadRows(Table table, std::string start_row_key,
                                bool inclusive, std::string limit_row_key,
                                const std::vector<std::string>& column_names,
                                size_t max_rows) = 0;

  // Deletes the given row from the given table, if it exists.
  virtual Status DeleteRow(Table table, std::string row_key) = 0;

  // Deletes the rows from the store whose row keys contain the given
  // |row_key_prefix| as a prefix.
  //
  // table: Which table to delete from.
  //
  // row_key_prefix: All rows with row keys that extend this prefix will be
  //     deleted. |row_key_prefix| cannot be empty. To delete all rows use
  //     DeleteAllRows().
  virtual Status DeleteRowsWithPrefix(Table table,
                                      std::string row_key_prefix) = 0;

  // Deletes all of the rows of the given table.
  //
  // WARNING: This permanently deletes all data from the table.
  virtual Status DeleteAllRows(Table table) = 0;
};

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

#endif  // COBALT_ANALYZER_STORE_DATA_STORE_H_
