// Copyright (c) 2017-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).

/**
 * The encoding of Cassandra Row Value.
 *
 * A Cassandra Row Value could either be a row tombstone,
 * or contains multiple columns, it has following fields:
 *
 * struct row_value {
 *   int32_t local_deletion_time;  // Time in second when the row is deleted,
 *                                 // only used for Cassandra tombstone gc.
 *   int64_t marked_for_delete_at; // Ms that marked this row is deleted.
 *   struct column_base columns[]; // For non tombstone row, all columns
 *                                 // are stored here.
 * }
 *
 * If the local_deletion_time and marked_for_delete_at is set, then this is
 * a tombstone, otherwise it contains multiple columns.
 *
 * There are three type of Columns: Normal Column, Expiring Column and Column
 * Tombstone, which have following fields:
 *
 * // Identify the type of the column.
 * enum mask {
 *   DELETION_MASK = 0x01,
 *   EXPIRATION_MASK = 0x02,
 * };
 *
 * struct column  {
 *   int8_t mask = 0;
 *   int8_t index;
 *   int64_t timestamp;
 *   int32_t value_length;
 *   char value[value_length];
 * }
 *
 * struct expiring_column  {
 *   int8_t mask = mask.EXPIRATION_MASK;
 *   int8_t index;
 *   int64_t timestamp;
 *   int32_t value_length;
 *   char value[value_length];
 *   int32_t ttl;
 * }
 *
 * struct tombstone_column  {
 *   int8_t mask = mask.DELETION_MASK;
 *   int8_t index;
 *   int32_t local_deletion_time; // Similar to row_value's field.
 *   int64_t marked_for_delete_at;
 *  }
 */

#pragma once
#include <chrono>
#include <vector>
#include <memory>
#include "rocksdb/merge_operator.h"
#include "rocksdb/slice.h"
#include "util/testharness.h"

namespace rocksdb {
namespace cassandra {

// Identify the type of the column.
enum ColumnTypeMask {
  DELETION_MASK = 0x01,
  EXPIRATION_MASK = 0x02,
};


class ColumnBase {
public:
  ColumnBase(int8_t mask, int8_t index);
  virtual ~ColumnBase() = default;

  virtual int64_t Timestamp() const = 0;
  virtual int8_t Mask() const;
  virtual int8_t Index() const;
  virtual std::size_t Size() const;
  virtual void Serialize(std::string* dest) const;
  static std::shared_ptr<ColumnBase> Deserialize(const char* src,
                                                 std::size_t offset);

private:
  int8_t mask_;
  int8_t index_;
};

class Column : public ColumnBase {
public:
  Column(int8_t mask, int8_t index, int64_t timestamp,
    int32_t value_size, const char* value);

  virtual int64_t Timestamp() const override;
  virtual std::size_t Size() const override;
  virtual void Serialize(std::string* dest) const override;
  static std::shared_ptr<Column> Deserialize(const char* src,
                                             std::size_t offset);

private:
  int64_t timestamp_;
  int32_t value_size_;
  const char* value_;
};

class Tombstone : public ColumnBase {
public:
  Tombstone(int8_t mask, int8_t index,
    int32_t local_deletion_time, int64_t marked_for_delete_at);

  virtual int64_t Timestamp() const override;
  virtual std::size_t Size() const override;
  virtual void Serialize(std::string* dest) const override;

  static std::shared_ptr<Tombstone> Deserialize(const char* src,
                                                std::size_t offset);

private:
  int32_t local_deletion_time_;
  int64_t marked_for_delete_at_;
};

class ExpiringColumn : public Column {
public:
  ExpiringColumn(int8_t mask, int8_t index, int64_t timestamp,
    int32_t value_size, const char* value, int32_t ttl);

  virtual std::size_t Size() const override;
  virtual void Serialize(std::string* dest) const override;
  bool Expired() const;
  std::shared_ptr<Tombstone> ToTombstone() const;

  static std::shared_ptr<ExpiringColumn> Deserialize(const char* src,
                                                     std::size_t offset);

private:
  int32_t ttl_;
  std::chrono::time_point<std::chrono::system_clock> TimePoint() const;
  std::chrono::seconds Ttl() const;
};

typedef std::vector<std::shared_ptr<ColumnBase>> Columns;

class RowValue {
public:
  // Create a Row Tombstone.
  RowValue(int32_t local_deletion_time, int64_t marked_for_delete_at);
  // Create a Row containing columns.
  RowValue(Columns columns,
           int64_t last_modified_time);
  RowValue(const RowValue& that) = delete;
  RowValue(RowValue&& that) noexcept = default;
  RowValue& operator=(const RowValue& that) = delete;
  RowValue& operator=(RowValue&& that) = default;

  std::size_t Size() const;;
  bool IsTombstone() const;
  // For Tombstone this returns the marked_for_delete_at_,
  // otherwise it returns the max timestamp of containing columns.
  int64_t LastModifiedTime() const;
  void Serialize(std::string* dest) const;
  RowValue PurgeTtl(bool* changed) const;
  RowValue ExpireTtl(bool* changed) const;
  bool Empty() const;

  static RowValue Deserialize(const char* src, std::size_t size);
  // Merge multiple rows according to their timestamp.
  static RowValue Merge(std::vector<RowValue>&& values);

private:
  int32_t local_deletion_time_;
  int64_t marked_for_delete_at_;
  Columns columns_;
  int64_t last_modified_time_;

};

} // namepsace cassandrda
} // namespace rocksdb
