/*
 * Copyright (C) 2018 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_SQLITE_QUERY_CONSTRAINTS_H_
#define SRC_TRACE_PROCESSOR_SQLITE_QUERY_CONSTRAINTS_H_

#include <limits>
#include <vector>

#include "perfetto/ext/base/scoped_file.h"

namespace perfetto {
namespace trace_processor {

// This class stores the constraints (including the order-by information) for
// a query on a sqlite3 virtual table and handles their de/serialization into
// strings.
// This is because the constraint columns and the order-by clauses are passed
// to the xBestIndex method but the constraint values are available only in the
// xFilter method. Unfortunately sqlite vtable API don't give any hint about
// the validity of the constraints (i.e. constraints passed to xBestIndex can
// be used by future xFilter calls in the far future). The only mechanism
// offered by sqlite is the idxStr string which is returned by the vtable
// in the xBestIndex call and passed to each corresponding xFilter call.
class QueryConstraints {
 public:
  struct Constraint {
    // Column this constraint refers to.
    int column;

    // SQLite op for the constraint.
    int op;

    // The original index of this constraint in the aConstraint array.
    // Used internally by SqliteTable for xBestIndex - this should not be
    // read or modified by subclasses of SqliteTable.
    int a_constraint_idx;
  };
  struct OrderBy {
    int iColumn;
    unsigned char desc;
  };

  static int FreeSqliteString(char* resource);

  using SqliteString = base::ScopedResource<char*, FreeSqliteString, nullptr>;

  explicit QueryConstraints(
      uint64_t cols_used = std::numeric_limits<uint64_t>::max());
  ~QueryConstraints();
  QueryConstraints(QueryConstraints&&) noexcept;
  QueryConstraints& operator=(QueryConstraints&&) noexcept;

  // Two QueryConstraints with the same constraint and orderby vectors
  // are equal.
  bool operator==(const QueryConstraints& other) const;

  void AddConstraint(int column, unsigned char op, int aconstraint_idx);

  void AddOrderBy(int column, unsigned char desc);

  void ClearOrderBy() { order_by_.clear(); }

  // Converts the constraints and order by information to a string for
  // use by sqlite.
  SqliteString ToNewSqlite3String() const;

  // Deserializes the string into QueryConstraints. String given is in the form
  // C{# of constraints},col1,op1,col2,op2...,O{# of order by},col1,desc1...
  // For example C1,0,3,O2,1,0,4,1
  static QueryConstraints FromString(const char* idxStr);

  const std::vector<OrderBy>& order_by() const { return order_by_; }

  const std::vector<Constraint>& constraints() const { return constraints_; }

  std::vector<OrderBy>* mutable_order_by() { return &order_by_; }

  std::vector<Constraint>* mutable_constraints() { return &constraints_; }

  uint64_t cols_used() const { return cols_used_; }

 private:
  QueryConstraints(const QueryConstraints&) = delete;
  QueryConstraints& operator=(const QueryConstraints&) = delete;

  std::vector<OrderBy> order_by_;
  std::vector<Constraint> constraints_;

  // Stores information about which column is used by this query.
  // If the lowest bit of is set, the first column is used. The second lowest
  // bit corresponds to the second column etc. If the most significant bit is
  // set, that means that any column after the first 63 columns could be used.
  uint64_t cols_used_ = std::numeric_limits<uint64_t>::max();
};

}  // namespace trace_processor
}  // namespace perfetto

#endif  // SRC_TRACE_PROCESSOR_SQLITE_QUERY_CONSTRAINTS_H_
