/*
 * 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_COMPARE_H_
#define SRC_TRACE_PROCESSOR_DB_COMPARE_H_

#include <stdint.h>

#include <algorithm>
#include <optional>

#include "perfetto/ext/base/string_view.h"
#include "perfetto/trace_processor/basic_types.h"

namespace perfetto {
namespace trace_processor {
namespace compare {

// This file contains the de-facto impleemntation of all comparisions used by
// trace processor in every setting. All of this is centralised in one file to
// ensure both internal consistency with SQLite and consistency with SQLite.

// Compare a non-null numeric to a double; returns:
//  * <0 if i < d,
//  * >0 if i > d.
//  *  0 otherwise
// This code matches the behaviour of sqlite3IntFloatCompare.
inline int LongToDouble(int64_t i, double d) {
  // First check if we are out of range for a int64_t. We use the constants
  // directly instead of using numeric_limits as the casts introduces rounding
  // in the doubles as a double cannot exactly represent int64::max().
  if (d >= 9223372036854775808.0)
    return -1;
  if (d < -9223372036854775808.0)
    return 1;

  // Then, try to compare in int64 space to try and keep as much precision as
  // possible.
  int64_t d_i = static_cast<int64_t>(d);
  if (i < d_i)
    return -1;
  if (i > d_i)
    return 1;

  // Finally, try and compare in double space, sacrificing precision if
  // necessary.
  double i_d = static_cast<double>(i);
  return (i_d < d) ? -1 : (i_d > d ? 1 : 0);
}

// Compares two non-null numeric values; returns:
//  * <0 if a < b,
//  * >0 if a > b.
//  *  0 otherwise
// This code matches the behaviour of the inline code in the comparision path of
// sqlite3VdbeExec (for ints) and the behaviour of sqlite3MemCompare (for
// doubles).
template <typename T>
inline int Numeric(T a, T b) {
  static_assert(std::is_arithmetic<T>::value,
                "Numeric comparision performed with non-numeric type");
  return a < b ? -1 : (a > b ? 1 : 0);
}

// Compares two non-null bytes values; returns:
//  * <0 if a < b,
//  * >0 if a > b.
//  *  0 otherwise
// This code matches the behaviour of sqlite3BlobCompare.
inline int Bytes(const void* a, size_t a_n, const void* b, size_t b_n) {
  int res = memcmp(a, b, std::min(a_n, b_n));
  return res != 0 ? res
                  : static_cast<int>(static_cast<int64_t>(a_n) -
                                     static_cast<int64_t>(b_n));
}

// Compares two non-null string values; returns:
//  * <0 if a < b,
//  * >0 if a > b.
//  *  0 otherwise
// This code matches the behaviour of sqlite3BlobCompare which is called when
// there is no collation sequence defined in sqlite3MemCompare.
inline int String(base::StringView a, base::StringView b) {
  PERFETTO_DCHECK(a.data() != nullptr);
  PERFETTO_DCHECK(b.data() != nullptr);
  return Bytes(a.data(), a.size(), b.data(), b.size());
}

// Compares two nullable numeric values; returns:
//  *  0 if both a and b are null
//  * <0 if a is null and b is non null
//  * >0 if a is non null and b is null
//  * <0 if a < b (a and b both non null)
//  * >0 if a > b (a and b both non null)
//  *  0 otherwise
// Should only be used for defining an ordering on value of type T. For filter
// functions, compare::Numeric should be used above after checking if the value
// is null.
// This method was defined from observing the behaviour of SQLite when sorting
// on columns containing nulls.
template <typename T>
inline int NullableNumeric(std::optional<T> a, std::optional<T> b) {
  if (!a)
    return b ? -1 : 0;

  if (!b)
    return 1;

  return compare::Numeric(*a, *b);
}

// Compares two strings, either of which can be null; returns:
//  *  0 if both a and b are null
//  * <0 if a is null and b is non null
//  * >0 if a is non null and b is null
//  * <0 if a < b (a and b both non null)
//  * >0 if a > b (a and b both non null)
//  *  0 otherwise
// Should only be used for defining an ordering on value of type T. For filter
// functions, compare::String should be used above after checking if the value
// is null.
// This method was defined from observing the behaviour of SQLite when sorting
// on columns containing nulls.
inline int NullableString(base::StringView a, base::StringView b) {
  if (!a.data())
    return b.data() ? -1 : 0;

  if (!b.data())
    return 1;

  return compare::String(a, b);
}

// Compares two SqlValue; returns:
//  * <0 if a.type < b.type and a and b are not both numeric
//  * >0 if a.type > b.type and a and b are not both numeric
//  * <0 if a < b (a and b both non null and either of same type or numeric)
//  * >0 if a > b (a and b both non null and either of same type or numeric)
//  *  0 otherwise
// This code roughly matches the behaviour of the code in the comparision path
// of sqlite3VdbeExec except we are intentionally more strict than SQLite when
// it comes to casting between strings and numerics - we disallow moving between
// the two. We do allow comparing between doubles and longs however as doubles
// can easily appear by using constants in SQL even when intending to use longs.
inline int SqlValue(const SqlValue& a, const SqlValue& b) {
  if (a.type != b.type) {
    if (a.type == SqlValue::kLong && b.type == SqlValue::kDouble)
      return compare::LongToDouble(a.long_value, b.double_value);

    if (a.type == SqlValue::kDouble && b.type == SqlValue::kLong)
      return -compare::LongToDouble(b.long_value, a.double_value);

    return a.type - b.type;
  }

  switch (a.type) {
    case SqlValue::Type::kLong:
      return compare::Numeric(a.long_value, b.long_value);
    case SqlValue::Type::kDouble:
      return compare::Numeric(a.double_value, b.double_value);
    case SqlValue::Type::kString:
      return compare::String(a.string_value, b.string_value);
    case SqlValue::Type::kBytes:
      return compare::Bytes(a.bytes_value, a.bytes_count, b.bytes_value,
                            b.bytes_count);
    case SqlValue::Type::kNull:
      return 0;
  }
  PERFETTO_FATAL("For GCC");
}

// Implements a comparator for SqlValues to use for std algorithms.
// See documentation of compare::SqlValue for details of how this function
// works.
inline int SqlValueComparator(const trace_processor::SqlValue& a,
                              const trace_processor::SqlValue& b) {
  return compare::SqlValue(a, b) < 0;
}

}  // namespace compare
}  // namespace trace_processor
}  // namespace perfetto

#endif  // SRC_TRACE_PROCESSOR_DB_COMPARE_H_
