/*
 * 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_UTILS_H_
#define SRC_TRACE_PROCESSOR_SQLITE_UTILS_H_

#include <math.h>
#include <sqlite3.h>

#include <functional>
#include <limits>
#include <string>

#include "perfetto/base/logging.h"
#include "perfetto/base/optional.h"
#include "src/trace_processor/scoped_db.h"
#include "src/trace_processor/table.h"

namespace perfetto {
namespace trace_processor {
namespace sqlite_utils {

const auto kSqliteStatic = reinterpret_cast<sqlite3_destructor_type>(0);
const auto kSqliteTransient = reinterpret_cast<sqlite3_destructor_type>(-1);

template <typename T>
using is_numeric =
    typename std::enable_if<std::is_arithmetic<T>::value, T>::type;

template <typename T>
using is_float =
    typename std::enable_if<std::is_floating_point<T>::value, T>::type;

template <typename T>
using is_int = typename std::enable_if<std::is_integral<T>::value, T>::type;

inline bool IsOpEq(int op) {
  return op == SQLITE_INDEX_CONSTRAINT_EQ;
}

inline bool IsOpGe(int op) {
  return op == SQLITE_INDEX_CONSTRAINT_GE;
}

inline bool IsOpGt(int op) {
  return op == SQLITE_INDEX_CONSTRAINT_GT;
}

inline bool IsOpLe(int op) {
  return op == SQLITE_INDEX_CONSTRAINT_LE;
}

inline bool IsOpLt(int op) {
  return op == SQLITE_INDEX_CONSTRAINT_LT;
}

inline std::string OpToString(int op) {
  switch (op) {
    case SQLITE_INDEX_CONSTRAINT_EQ:
      return "=";
    case SQLITE_INDEX_CONSTRAINT_NE:
      return "!=";
    case SQLITE_INDEX_CONSTRAINT_GE:
      return ">=";
    case SQLITE_INDEX_CONSTRAINT_GT:
      return ">";
    case SQLITE_INDEX_CONSTRAINT_LE:
      return "<=";
    case SQLITE_INDEX_CONSTRAINT_LT:
      return "<";
    default:
      PERFETTO_FATAL("Operator to string conversion not impemented for %d", op);
  }
}

inline bool IsOpIsNull(int op) {
  return op == SQLITE_INDEX_CONSTRAINT_ISNULL;
}

inline bool IsOpIsNotNull(int op) {
  return op == SQLITE_INDEX_CONSTRAINT_ISNOTNULL;
}

template <typename T>
T ExtractSqliteValue(sqlite3_value* value);

template <>
inline uint8_t ExtractSqliteValue(sqlite3_value* value) {
  auto type = sqlite3_value_type(value);
  PERFETTO_DCHECK(type == SQLITE_INTEGER);
  return static_cast<uint8_t>(sqlite3_value_int(value));
}

template <>
inline uint32_t ExtractSqliteValue(sqlite3_value* value) {
  auto type = sqlite3_value_type(value);
  PERFETTO_DCHECK(type == SQLITE_INTEGER);
  return static_cast<uint32_t>(sqlite3_value_int64(value));
}

template <>
inline int32_t ExtractSqliteValue(sqlite3_value* value) {
  auto type = sqlite3_value_type(value);
  PERFETTO_DCHECK(type == SQLITE_INTEGER);
  return sqlite3_value_int(value);
}

template <>
inline int64_t ExtractSqliteValue(sqlite3_value* value) {
  auto type = sqlite3_value_type(value);
  PERFETTO_DCHECK(type == SQLITE_INTEGER);
  return static_cast<int64_t>(sqlite3_value_int64(value));
}

template <>
inline double ExtractSqliteValue(sqlite3_value* value) {
  auto type = sqlite3_value_type(value);
  PERFETTO_DCHECK(type == SQLITE_FLOAT || type == SQLITE_INTEGER);
  return sqlite3_value_double(value);
}

// Do not add a uint64_t version of ExtractSqliteValue. You should not be using
// uint64_t at all given that SQLite doesn't support it.

template <>
inline std::string ExtractSqliteValue(sqlite3_value* value) {
  auto type = sqlite3_value_type(value);
  PERFETTO_DCHECK(type == SQLITE_TEXT);
  const auto* extracted =
      reinterpret_cast<const char*>(sqlite3_value_text(value));
  return std::string(extracted);
}

template <typename T>
class NumericPredicate {
 public:
  NumericPredicate(int op, T constant) : op_(op), constant_(constant) {}

  PERFETTO_ALWAYS_INLINE bool operator()(T other) const {
    switch (op_) {
      case SQLITE_INDEX_CONSTRAINT_ISNULL:
        return false;
      case SQLITE_INDEX_CONSTRAINT_ISNOTNULL:
        return true;
      case SQLITE_INDEX_CONSTRAINT_EQ:
      case SQLITE_INDEX_CONSTRAINT_IS:
        return std::equal_to<T>()(other, constant_);
      case SQLITE_INDEX_CONSTRAINT_NE:
      case SQLITE_INDEX_CONSTRAINT_ISNOT:
        return std::not_equal_to<T>()(other, constant_);
      case SQLITE_INDEX_CONSTRAINT_GE:
        return std::greater_equal<T>()(other, constant_);
      case SQLITE_INDEX_CONSTRAINT_GT:
        return std::greater<T>()(other, constant_);
      case SQLITE_INDEX_CONSTRAINT_LE:
        return std::less_equal<T>()(other, constant_);
      case SQLITE_INDEX_CONSTRAINT_LT:
        return std::less<T>()(other, constant_);
      default:
        PERFETTO_FATAL("For GCC");
    }
  }

 private:
  int op_;
  T constant_;
};

template <typename T, typename sqlite_utils::is_numeric<T>* = nullptr>
NumericPredicate<T> CreateNumericPredicate(int op, sqlite3_value* value) {
  T extracted =
      IsOpIsNull(op) || IsOpIsNotNull(op) ? 0 : ExtractSqliteValue<T>(value);
  return NumericPredicate<T>(op, extracted);
}

inline std::function<bool(const char*)> CreateStringPredicate(
    int op,
    sqlite3_value* value) {
  switch (op) {
    case SQLITE_INDEX_CONSTRAINT_ISNULL:
      return [](const char* f) { return f == nullptr; };
    case SQLITE_INDEX_CONSTRAINT_ISNOTNULL:
      return [](const char* f) { return f != nullptr; };
  }

  const char* val = reinterpret_cast<const char*>(sqlite3_value_text(value));

  // If the value compared against is null, then to stay consistent with SQL
  // handling, we have to return false for non-null operators.
  if (val == nullptr) {
    PERFETTO_CHECK(op != SQLITE_INDEX_CONSTRAINT_IS &&
                   op != SQLITE_INDEX_CONSTRAINT_ISNOT);
    return [](const char*) { return false; };
  }

  switch (op) {
    case SQLITE_INDEX_CONSTRAINT_EQ:
    case SQLITE_INDEX_CONSTRAINT_IS:
      return [val](const char* str) {
        return str != nullptr && strcmp(str, val) == 0;
      };
    case SQLITE_INDEX_CONSTRAINT_NE:
    case SQLITE_INDEX_CONSTRAINT_ISNOT:
      return [val](const char* str) {
        return str != nullptr && strcmp(str, val) != 0;
      };
    case SQLITE_INDEX_CONSTRAINT_GE:
      return [val](const char* str) {
        return str != nullptr && strcmp(str, val) >= 0;
      };
    case SQLITE_INDEX_CONSTRAINT_GT:
      return [val](const char* str) {
        return str != nullptr && strcmp(str, val) > 0;
      };
    case SQLITE_INDEX_CONSTRAINT_LE:
      return [val](const char* str) {
        return str != nullptr && strcmp(str, val) <= 0;
      };
    case SQLITE_INDEX_CONSTRAINT_LT:
      return [val](const char* str) {
        return str != nullptr && strcmp(str, val) < 0;
      };
    case SQLITE_INDEX_CONSTRAINT_LIKE:
      return [val](const char* str) {
        return str != nullptr && sqlite3_strlike(val, str, 0) == 0;
      };
    case SQLITE_INDEX_CONSTRAINT_GLOB:
      return [val](const char* str) {
        return str != nullptr && sqlite3_strglob(val, str) == 0;
      };
    default:
      PERFETTO_FATAL("For GCC");
  }
}

// Greater bound for floating point numbers.
template <typename T, typename sqlite_utils::is_float<T>* = nullptr>
T FindGtBound(bool is_eq, sqlite3_value* sqlite_val) {
  constexpr auto kMax = static_cast<long double>(std::numeric_limits<T>::max());
  auto type = sqlite3_value_type(sqlite_val);
  if (type != SQLITE_INTEGER && type != SQLITE_FLOAT) {
    return kMax;
  }

  // If this is a strict gt bound then just get the next highest float
  // after value.
  auto value = ExtractSqliteValue<T>(sqlite_val);
  return is_eq ? value : nexttoward(value, kMax);
}

template <typename T, typename sqlite_utils::is_int<T>* = nullptr>
T FindGtBound(bool is_eq, sqlite3_value* sqlite_val) {
  auto type = sqlite3_value_type(sqlite_val);
  if (type == SQLITE_INTEGER) {
    auto value = ExtractSqliteValue<T>(sqlite_val);
    return is_eq ? value : value + 1;
  } else if (type == SQLITE_FLOAT) {
    auto value = ExtractSqliteValue<double>(sqlite_val);
    auto above = ceil(value);
    auto cast = static_cast<T>(above);
    return value < above ? cast : (is_eq ? cast : cast + 1);
  } else {
    return std::numeric_limits<T>::max();
  }
}

template <typename T, typename sqlite_utils::is_float<T>* = nullptr>
T FindLtBound(bool is_eq, sqlite3_value* sqlite_val) {
  constexpr auto kMin =
      static_cast<long double>(std::numeric_limits<T>::lowest());
  auto type = sqlite3_value_type(sqlite_val);
  if (type != SQLITE_INTEGER && type != SQLITE_FLOAT) {
    return kMin;
  }

  // If this is a strict lt bound then just get the next lowest float
  // before value.
  auto value = ExtractSqliteValue<T>(sqlite_val);
  return is_eq ? value : nexttoward(value, kMin);
}

template <typename T, typename sqlite_utils::is_int<T>* = nullptr>
T FindLtBound(bool is_eq, sqlite3_value* sqlite_val) {
  auto type = sqlite3_value_type(sqlite_val);
  if (type == SQLITE_INTEGER) {
    auto value = ExtractSqliteValue<T>(sqlite_val);
    return is_eq ? value : value - 1;
  } else if (type == SQLITE_FLOAT) {
    auto value = ExtractSqliteValue<double>(sqlite_val);
    auto below = floor(value);
    auto cast = static_cast<T>(below);
    return value > below ? cast : (is_eq ? cast : cast - 1);
  } else {
    return std::numeric_limits<T>::max();
  }
}

template <typename T, typename sqlite_utils::is_float<T>* = nullptr>
T FindEqBound(sqlite3_value* sqlite_val) {
  auto type = sqlite3_value_type(sqlite_val);
  if (type != SQLITE_INTEGER && type != SQLITE_FLOAT) {
    return std::numeric_limits<T>::max();
  }
  return ExtractSqliteValue<T>(sqlite_val);
}

template <typename T, typename sqlite_utils::is_int<T>* = nullptr>
T FindEqBound(sqlite3_value* sqlite_val) {
  auto type = sqlite3_value_type(sqlite_val);
  if (type == SQLITE_INTEGER) {
    return ExtractSqliteValue<T>(sqlite_val);
  } else if (type == SQLITE_FLOAT) {
    auto value = ExtractSqliteValue<double>(sqlite_val);
    auto below = floor(value);
    auto cast = static_cast<T>(below);
    return value > below ? std::numeric_limits<T>::max() : cast;
  } else {
    return std::numeric_limits<T>::max();
  }
}

template <typename T>
void ReportSqliteResult(sqlite3_context*, T value);

// Do not add a uint64_t version of ReportSqliteResult. You should not be using
// uint64_t at all given that SQLite doesn't support it.

template <>
inline void ReportSqliteResult(sqlite3_context* ctx, int32_t value) {
  sqlite3_result_int(ctx, value);
}

template <>
inline void ReportSqliteResult(sqlite3_context* ctx, int64_t value) {
  sqlite3_result_int64(ctx, value);
}

template <>
inline void ReportSqliteResult(sqlite3_context* ctx, uint8_t value) {
  sqlite3_result_int(ctx, value);
}

template <>
inline void ReportSqliteResult(sqlite3_context* ctx, uint32_t value) {
  sqlite3_result_int64(ctx, value);
}

template <>
inline void ReportSqliteResult(sqlite3_context* ctx, double value) {
  sqlite3_result_double(ctx, value);
}

inline std::string SqliteValueAsString(sqlite3_value* value) {
  switch (sqlite3_value_type(value)) {
    case SQLITE_INTEGER:
      return std::to_string(sqlite3_value_int64(value));
    case SQLITE_FLOAT:
      return std::to_string(sqlite3_value_double(value));
    case SQLITE_TEXT: {
      const char* str =
          reinterpret_cast<const char*>(sqlite3_value_text(value));
      return "'" + std::string(str) + "'";
    }
    default:
      PERFETTO_FATAL("Unknown value type %d", sqlite3_value_type(value));
  }
}

inline std::vector<Table::Column> GetColumnsForTable(
    sqlite3* db,
    const std::string& raw_table_name) {
  char sql[1024];
  const char kRawSql[] = "SELECT name, type from pragma_table_info(\"%s\")";

  // Support names which are table valued functions with arguments.
  std::string table_name = raw_table_name.substr(0, raw_table_name.find('('));
  int n = snprintf(sql, sizeof(sql), kRawSql, table_name.c_str());
  PERFETTO_DCHECK(n >= 0 || static_cast<size_t>(n) < sizeof(sql));

  sqlite3_stmt* raw_stmt = nullptr;
  int err = sqlite3_prepare_v2(db, sql, n, &raw_stmt, nullptr);

  ScopedStmt stmt(raw_stmt);
  PERFETTO_DCHECK(sqlite3_column_count(*stmt) == 2);

  std::vector<Table::Column> columns;
  for (;;) {
    err = sqlite3_step(raw_stmt);
    if (err == SQLITE_DONE)
      break;
    if (err != SQLITE_ROW) {
      PERFETTO_ELOG("Querying schema of table %s failed",
                    raw_table_name.c_str());
      return {};
    }

    const char* name =
        reinterpret_cast<const char*>(sqlite3_column_text(*stmt, 0));
    const char* raw_type =
        reinterpret_cast<const char*>(sqlite3_column_text(*stmt, 1));
    if (!name || !raw_type || !*name) {
      PERFETTO_FATAL("Schema for %s has invalid column values",
                     raw_table_name.c_str());
    }

    Table::ColumnType type;
    if (strcmp(raw_type, "UNSIGNED INT") == 0) {
      type = Table::ColumnType::kUint;
    } else if (strcmp(raw_type, "BIG INT") == 0) {
      type = Table::ColumnType::kLong;
    } else if (strcmp(raw_type, "INT") == 0) {
      type = Table::ColumnType::kInt;
    } else if (strcmp(raw_type, "STRING") == 0) {
      type = Table::ColumnType::kString;
    } else if (strcmp(raw_type, "DOUBLE") == 0) {
      type = Table::ColumnType::kDouble;
    } else if (!*raw_type) {
      PERFETTO_DLOG("Unknown column type for %s %s", raw_table_name.c_str(),
                    name);
      type = Table::ColumnType::kUnknown;
    } else {
      PERFETTO_FATAL("Unknown column type '%s' on table %s", raw_type,
                     raw_table_name.c_str());
    }
    columns.emplace_back(columns.size(), name, type);
  }
  return columns;
}

template <typename T>
int CompareValuesAsc(const T& f, const T& s) {
  return f < s ? -1 : (f > s ? 1 : 0);
}

template <typename T>
int CompareValuesDesc(const T& f, const T& s) {
  return -CompareValuesAsc(f, s);
}

}  // namespace sqlite_utils
}  // namespace trace_processor
}  // namespace perfetto

#endif  // SRC_TRACE_PROCESSOR_SQLITE_UTILS_H_
