/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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 SRC_TRACE_PROCESSOR_DB_COLUMN_H_
#define SRC_TRACE_PROCESSOR_DB_COLUMN_H_

#include <stdint.h>
#include <optional>

#include "perfetto/base/logging.h"
#include "perfetto/trace_processor/basic_types.h"
#include "src/trace_processor/containers/row_map.h"
#include "src/trace_processor/containers/string_pool.h"
#include "src/trace_processor/db/column/types.h"
#include "src/trace_processor/db/column_storage.h"
#include "src/trace_processor/db/column_storage_overlay.h"
#include "src/trace_processor/db/compare.h"
#include "src/trace_processor/db/typed_column_internal.h"

namespace perfetto::trace_processor {

// Helper class for converting a type to a ColumnType.
template <typename T>
struct ColumnTypeHelper;
template <>
struct ColumnTypeHelper<int32_t> {
  static constexpr ColumnType ToColumnType() { return ColumnType::kInt32; }
};
template <>
struct ColumnTypeHelper<uint32_t> {
  static constexpr ColumnType ToColumnType() { return ColumnType::kUint32; }
};
template <>
struct ColumnTypeHelper<int64_t> {
  static constexpr ColumnType ToColumnType() { return ColumnType::kInt64; }
};
template <>
struct ColumnTypeHelper<double> {
  static constexpr ColumnType ToColumnType() { return ColumnType::kDouble; }
};
template <>
struct ColumnTypeHelper<StringPool::Id> {
  static constexpr ColumnType ToColumnType() { return ColumnType::kString; }
};
template <typename T>
struct ColumnTypeHelper<std::optional<T>> : public ColumnTypeHelper<T> {};

class Table;

// Represents a named, strongly typed list of data.
class ColumnLegacy {
 public:
  // Flags which indicate properties of the data in the column. These features
  // are used to speed up column methods like filtering/sorting.
  enum Flag : uint32_t {
    // Indicates that this column has no special properties.
    kNoFlag = 0,

    // Indicates the data in the column is sorted. This can be used to speed
    // up filtering and skip sorting.
    kSorted = 1 << 0,

    // Indicates the data in the column is non-null. That is, the NullableVector
    // passed in will never have any null entries. This is only used for
    // numeric columns (string columns and id columns both have special
    // handling which ignores this flag).
    //
    // This is used to speed up filters as we can safely index NullableVector
    // directly if this flag is set.
    kNonNull = 1 << 1,

    // Indicates that the data in the column is "hidden". This can by used to
    // hint to users of Table and Column that this column should not be
    // displayed to the user as it is part of the internal implementation
    // details of the table.
    kHidden = 1 << 2,

    // Indicates that the data in this column is stored densely. This
    // allows for fast Set calls to change the data in the column.
    //
    // This flag is only meaningful for nullable columns has no effect for
    // non-null columns.
    kDense = 1 << 3,

    // Indicates that the sorted numeric data in the column is laid out such
    // that at row i, we will always have col[i] <= i and the first element, j
    // of each group happens at the index j.
    //
    // This is a common pattern in trace processor and columns with this
    // property are suffixed with "set_id" hence the name of this flag.
    //
    // To make this clear, here are some valid and invalid uses of this flag.
    //
    // Valid:
    // []
    // [0]
    // [0, 1, 2]
    // [0, 0, 2]
    // [0, 0, 0, 3, 3, 5, 6, 6, 7]
    //
    // Invalid:
    // [1]
    // [0, 0, 1]
    // [0, 0, 2, 5]
    // [0, 0, 2, 1]
    //
    // If this flag is set, kSorted and kNonNull should be set. Moreover, this
    // flag can only be set when the type is ColumnType::kUint32; other types
    // are not supported.
    kSetId = 1 << 4,
  };

  // Iterator over a column which conforms to std iterator interface
  // to allow using std algorithms (e.g. upper_bound, lower_bound etc.).
  class Iterator {
   public:
    using iterator_category = std::random_access_iterator_tag;
    using value_type = SqlValue;
    using difference_type = uint32_t;
    using pointer = uint32_t*;
    using reference = uint32_t&;

    Iterator(const ColumnLegacy* col, uint32_t row) : col_(col), row_(row) {}

    Iterator(const Iterator&) = default;
    Iterator& operator=(const Iterator&) = default;

    bool operator==(const Iterator& other) const { return other.row_ == row_; }
    bool operator!=(const Iterator& other) const { return !(*this == other); }
    bool operator<(const Iterator& other) const { return row_ < other.row_; }
    bool operator>(const Iterator& other) const { return other < *this; }
    bool operator<=(const Iterator& other) const { return !(other < *this); }
    bool operator>=(const Iterator& other) const { return !(*this < other); }

    SqlValue operator*() const { return col_->Get(row_); }
    Iterator& operator++() {
      row_++;
      return *this;
    }
    Iterator& operator--() {
      row_--;
      return *this;
    }

    Iterator& operator+=(uint32_t diff) {
      row_ += diff;
      return *this;
    }
    uint32_t operator-(const Iterator& other) const {
      return row_ - other.row_;
    }

    uint32_t row() const { return row_; }

   private:
    const ColumnLegacy* col_ = nullptr;
    uint32_t row_ = 0;
  };

  // Flags specified for an id column.
  static constexpr uint32_t kIdFlags = Flag::kSorted | Flag::kNonNull;

  // Flags which should *not* be inherited implicitly when a column is
  // assocaited to another table.
  static constexpr uint32_t kNoCrossTableInheritFlags =
      ColumnLegacy::Flag::kSetId;

  template <typename T>
  ColumnLegacy(const char* name,
               ColumnStorage<T>* storage,
               /* Flag */ uint32_t flags,
               uint32_t col_idx_in_table,
               uint32_t row_map_idx)
      : ColumnLegacy(name,
                     ColumnTypeHelper<stored_type<T>>::ToColumnType(),
                     flags,
                     col_idx_in_table,
                     row_map_idx,
                     storage) {}

  // Create a Column backed by the same data as |column| but is associated to a
  // different table and, optionally, having a different name.
  ColumnLegacy(const ColumnLegacy& column,
               uint32_t col_idx_in_table,
               uint32_t row_map_idx,
               const char* name = nullptr);

  // Columns are movable but not copyable.
  ColumnLegacy(ColumnLegacy&&) noexcept = default;
  ColumnLegacy& operator=(ColumnLegacy&&) = default;

  // Creates a Column which does not have any data backing it.
  static ColumnLegacy DummyColumn(const char* name, uint32_t col_idx_in_table);

  // Creates a Column which returns the index as the value of the row.
  static ColumnLegacy IdColumn(uint32_t col_idx_in_table,
                               uint32_t overlay_idx,
                               const char* name = "id",
                               uint32_t flags = kIdFlags);

  // Gets the value of the Column at the given |row|.
  SqlValue Get(uint32_t row) const { return GetAtIdx(overlay().Get(row)); }

  // Returns the backing RowMap for this Column.
  // This function is defined out of line because of a circular dependency
  // between |Table| and |Column|.
  const ColumnStorageOverlay& overlay() const;

  // Returns the name of the column.
  const char* name() const { return name_; }

  // Returns the type of this Column in terms of ColumnType.
  ColumnType col_type() const { return type_; }

  // Test the type of this Column.
  template <typename T>
  bool IsColumnType() const {
    return ColumnTypeHelper<T>::ToColumnType() == type_;
  }

  // Returns true if this column is considered an id column.
  bool IsId() const { return type_ == ColumnType::kId; }

  // Returns true if this column is a nullable column.
  bool IsNullable() const { return IsNullable(flags_); }

  // Returns true if this column is a sorted column.
  bool IsSorted() const { return IsSorted(flags_); }

  // Returns true if this column is a dense column.
  bool IsDense() const { return IsDense(flags_); }

  // Returns true if this column is a set id column.
  // Public for testing.
  bool IsSetId() const { return IsSetId(flags_); }

  // Returns true if this column is a dummy column.
  // Public for testing.
  bool IsDummy() const { return type_ == ColumnType::kDummy; }

  // Returns true if this column is a hidden column.
  bool IsHidden() const { return (flags_ & Flag::kHidden) != 0; }

  // Returns the index of the RowMap in the containing table.
  uint32_t overlay_index() const { return overlay_index_; }

  // Returns the index of the current column in the containing table.
  uint32_t index_in_table() const { return index_in_table_; }

  // Returns a Constraint for each type of filter operation for this Column.
  Constraint eq_value(SqlValue value) const {
    return Constraint{index_in_table_, FilterOp::kEq, value};
  }
  Constraint gt_value(SqlValue value) const {
    return Constraint{index_in_table_, FilterOp::kGt, value};
  }
  Constraint lt_value(SqlValue value) const {
    return Constraint{index_in_table_, FilterOp::kLt, value};
  }
  Constraint ne_value(SqlValue value) const {
    return Constraint{index_in_table_, FilterOp::kNe, value};
  }
  Constraint ge_value(SqlValue value) const {
    return Constraint{index_in_table_, FilterOp::kGe, value};
  }
  Constraint le_value(SqlValue value) const {
    return Constraint{index_in_table_, FilterOp::kLe, value};
  }
  Constraint is_not_null() const {
    return Constraint{index_in_table_, FilterOp::kIsNotNull, SqlValue()};
  }
  Constraint is_null() const {
    return Constraint{index_in_table_, FilterOp::kIsNull, SqlValue()};
  }
  Constraint glob_value(SqlValue value) const {
    return Constraint{index_in_table_, FilterOp::kGlob, value};
  }

  Constraint regex_value(SqlValue value) const {
    return Constraint{index_in_table_, FilterOp::kRegex, value};
  }

  // Returns an Order for each Order type for this Column.
  Order ascending() const { return Order{index_in_table_, false}; }
  Order descending() const { return Order{index_in_table_, true}; }

  // Returns an iterator to the first entry in this column.
  Iterator begin() const { return Iterator(this, 0); }

  // Returns an iterator pointing beyond the last entry in this column.
  Iterator end() const { return Iterator(this, overlay().size()); }

  // Returns whether the given combination of flags when the column has the
  // given type is valid.
  template <typename T>
  static constexpr bool IsFlagsAndTypeValid(uint32_t flags) {
    return IsFlagsAndTypeValid(flags, ColumnTypeHelper<T>::ToColumnType());
  }

  template <typename T>
  using stored_type = typename tc_internal::TypeHandler<T>::stored_type;

  // Returns the backing sparse vector cast to contain data of type T.
  // Should only be called when |type_| == ToColumnType<T>().
  template <typename T>
  const ColumnStorage<stored_type<T>>& storage() const {
    PERFETTO_DCHECK(ColumnTypeHelper<T>::ToColumnType() == type_);
    PERFETTO_DCHECK(tc_internal::TypeHandler<T>::is_optional == IsNullable());
    return *static_cast<ColumnStorage<stored_type<T>>*>(storage_);
  }

  const ColumnStorageBase& storage_base() const { return *storage_; }

  static SqlValue::Type ToSqlValueType(ColumnType type) {
    switch (type) {
      case ColumnType::kInt32:
      case ColumnType::kUint32:
      case ColumnType::kInt64:
      case ColumnType::kId:
        return SqlValue::Type::kLong;
      case ColumnType::kDouble:
        return SqlValue::Type::kDouble;
      case ColumnType::kString:
        return SqlValue::Type::kString;
      case ColumnType::kDummy:
        PERFETTO_FATAL("ToSqlValueType not allowed on dummy column");
    }
    PERFETTO_FATAL("For GCC");
  }

 protected:
  // Returns the backing sparse vector cast to contain data of type T.
  // Should only be called when |type_| == ToColumnType<T>().
  template <typename T>
  ColumnStorage<stored_type<T>>* mutable_storage() {
    PERFETTO_DCHECK(ColumnTypeHelper<T>::ToColumnType() == type_);
    PERFETTO_DCHECK(tc_internal::TypeHandler<T>::is_optional == IsNullable());
    return static_cast<ColumnStorage<stored_type<T>>*>(storage_);
  }

  const StringPool& string_pool() const { return *string_pool_; }

  // Returns the type of this Column in terms of SqlValue::Type.
  template <typename T>
  static SqlValue::Type ToSqlValueType() {
    return ToSqlValueType(ColumnTypeHelper<T>::ToColumnType());
  }

  static SqlValue ToSqlValue(double value) { return SqlValue::Double(value); }
  static SqlValue ToSqlValue(int32_t value) { return SqlValue::Long(value); }
  static SqlValue ToSqlValue(uint32_t value) { return SqlValue::Long(value); }
  static SqlValue ToSqlValue(int64_t value) { return SqlValue::Long(value); }
  static SqlValue ToSqlValue(NullTermStringView value) {
    return SqlValue::String(value.c_str());
  }

 private:
  friend class Table;
  friend class View;

  // Base constructor for this class which all other constructors call into.
  ColumnLegacy(const char* name,
               ColumnType type,
               uint32_t flags,
               uint32_t col_idx_in_table,
               uint32_t overlay_index,
               ColumnStorageBase* nullable_vector);

  ColumnLegacy(const ColumnLegacy&) = delete;
  ColumnLegacy& operator=(const ColumnLegacy&) = delete;

  // Gets the value of the Column at the given |idx|.
  SqlValue GetAtIdx(uint32_t idx) const {
    switch (type_) {
      case ColumnType::kInt32:
        return GetAtIdxTyped<int32_t>(idx);
      case ColumnType::kUint32:
        return GetAtIdxTyped<uint32_t>(idx);
      case ColumnType::kInt64:
        return GetAtIdxTyped<int64_t>(idx);
      case ColumnType::kDouble:
        return GetAtIdxTyped<double>(idx);
      case ColumnType::kString: {
        auto str = GetStringPoolStringAtIdx(idx).c_str();
        return str == nullptr ? SqlValue() : SqlValue::String(str);
      }
      case ColumnType::kId:
        return SqlValue::Long(idx);
      case ColumnType::kDummy:
        PERFETTO_FATAL("GetAtIdx not allowed on dummy column");
    }
    PERFETTO_FATAL("For GCC");
  }

  template <typename T>
  SqlValue GetAtIdxTyped(uint32_t idx) const {
    if (IsNullable()) {
      auto opt_value = storage<std::optional<T>>().Get(idx);
      return opt_value ? ToSqlValue(*opt_value) : SqlValue();
    }
    return ToSqlValue(storage<T>().Get(idx));
  }

  static constexpr bool IsDense(uint32_t flags) {
    return (flags & Flag::kDense) != 0;
  }
  static constexpr bool IsNullable(uint32_t flags) {
    return (flags & Flag::kNonNull) == 0;
  }
  static constexpr bool IsSetId(uint32_t flags) {
    return (flags & Flag::kSetId) != 0;
  }
  static constexpr bool IsSorted(uint32_t flags) {
    return (flags & Flag::kSorted) != 0;
  }

  static constexpr bool IsFlagsAndTypeValid(uint32_t flags, ColumnType type) {
    return (!IsDense(flags) || IsFlagsForDenseValid(flags)) &&
           (!IsSetId(flags) || IsFlagsAndTypeForSetIdValid(flags, type));
  }

  static constexpr bool IsFlagsForDenseValid(uint32_t flags) {
    // The dense flag should only be set when the column is nullable.
    return IsNullable(flags);
  }

  static constexpr bool IsFlagsAndTypeForSetIdValid(uint32_t flags,
                                                    ColumnType type) {
    // The sorted flag should always be set for set id columns.
    // The non-null flag should always be set for set id columns.
    // The column type should always be kUint32.
    return IsSorted(flags) && !IsNullable(flags) && type == ColumnType::kUint32;
  }

  // Returns the string at the index |idx|.
  // Should only be called when |type_| == ColumnType::kString.
  NullTermStringView GetStringPoolStringAtIdx(uint32_t idx) const {
    PERFETTO_DCHECK(type_ == ColumnType::kString);
    return string_pool_->Get(storage<StringPool::Id>().Get(idx));
  }

  void BindToTable(Table* table, StringPool* string_pool) {
    PERFETTO_DCHECK(!table_);
    table_ = table;
    string_pool_ = string_pool;

    // Check that the dense-ness of the column and the nullable vector match.
    if (IsNullable() && !IsDummy()) {
      bool is_storage_dense;
      switch (type_) {
        case ColumnType::kInt32:
          is_storage_dense = storage<std::optional<int32_t>>().IsDense();
          break;
        case ColumnType::kUint32:
          is_storage_dense = storage<std::optional<uint32_t>>().IsDense();
          break;
        case ColumnType::kInt64:
          is_storage_dense = storage<std::optional<int64_t>>().IsDense();
          break;
        case ColumnType::kDouble:
          is_storage_dense = storage<std::optional<double>>().IsDense();
          break;
        case ColumnType::kString:
          PERFETTO_FATAL("String column should not be nullable");
        case ColumnType::kId:
          PERFETTO_FATAL("Id column should not be nullable");
        case ColumnType::kDummy:
          PERFETTO_FATAL("Dummy column excluded above");
      }
      PERFETTO_DCHECK(is_storage_dense == IsDense());
    }
    PERFETTO_DCHECK(IsFlagsAndTypeValid(flags_, type_));
  }

  // type_ is used to cast nullable_vector_ to the correct type.
  ColumnType type_ = ColumnType::kInt64;
  ColumnStorageBase* storage_ = nullptr;

  const char* name_ = nullptr;
  uint32_t flags_ = Flag::kNoFlag;
  const Table* table_ = nullptr;
  uint32_t index_in_table_ = 0;
  uint32_t overlay_index_ = 0;
  const StringPool* string_pool_ = nullptr;
};

}  // namespace perfetto::trace_processor

#endif  // SRC_TRACE_PROCESSOR_DB_COLUMN_H_
