/*
 * 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.
 */

#include "src/trace_processor/query_constraints.h"

#include <sqlite3.h>
#include <string>

#include "include/perfetto/base/string_splitter.h"

namespace perfetto {
namespace trace_processor {

QueryConstraints::QueryConstraints() = default;
QueryConstraints::~QueryConstraints() = default;
QueryConstraints::QueryConstraints(QueryConstraints&&) noexcept = default;
QueryConstraints& QueryConstraints::operator=(QueryConstraints&&) = default;

int QueryConstraints::FreeSqliteString(char* resource) {
  sqlite3_free(resource);
  return 0;
}

bool QueryConstraints::operator==(const QueryConstraints& other) const {
  if ((other.constraints().size() != constraints().size()) ||
      (other.order_by().size() != order_by().size())) {
    return false;
  }

  for (size_t i = 0; i < constraints().size(); ++i) {
    if ((constraints()[i].iColumn != other.constraints()[i].iColumn) ||
        (constraints()[i].op != other.constraints()[i].op)) {
      return false;
    }
  }

  for (size_t i = 0; i < order_by().size(); ++i) {
    if ((order_by()[i].iColumn != other.order_by()[i].iColumn) ||
        (order_by()[i].desc != other.order_by()[i].desc)) {
      return false;
    }
  }

  return true;
}

void QueryConstraints::AddConstraint(int column, unsigned char op) {
  Constraint c{};
  c.iColumn = column;
  c.op = op;
  constraints_.emplace_back(c);
}

void QueryConstraints::AddOrderBy(int column, unsigned char desc) {
  OrderBy ob{};
  ob.iColumn = column;
  ob.desc = desc;
  order_by_.emplace_back(ob);
}

QueryConstraints::SqliteString QueryConstraints::ToNewSqlite3String() const {
  std::string str_result;
  str_result.reserve(512);
  str_result.append("C");
  str_result.append(std::to_string(constraints_.size()));
  str_result.append(",");
  for (const auto& cs : constraints_) {
    str_result.append(std::to_string(cs.iColumn));
    str_result.append(",");
    str_result.append(std::to_string(cs.op));
    str_result.append(",");
  }
  str_result.append("O");
  str_result.append(std::to_string(order_by_.size()));
  str_result.append(",");
  for (const auto& ob : order_by_) {
    str_result.append(std::to_string(ob.iColumn));
    str_result.append(",");
    str_result.append(std::to_string(ob.desc));
    str_result.append(",");
  }

  // The last char is a "," so overwriting with the null terminator on purpose.
  SqliteString result(
      static_cast<char*>(sqlite3_malloc(static_cast<int>(str_result.size()))));
  strncpy(result.get(), str_result.c_str(), str_result.size());
  (*result)[str_result.size() - 1] = '\0';

  return result;
}

QueryConstraints QueryConstraints::FromString(const char* idxStr) {
  QueryConstraints qc;

  base::StringSplitter splitter(std::string(idxStr), ',');

  PERFETTO_CHECK(splitter.Next() && splitter.cur_token_size() > 1);
  // The '+ 1' skips the letter 'C' in the first token.
  long num_constraints = strtol(splitter.cur_token() + 1, nullptr, 10);
  for (int i = 0; i < num_constraints; ++i) {
    PERFETTO_CHECK(splitter.Next());
    int col = static_cast<int>(strtol(splitter.cur_token(), nullptr, 10));
    PERFETTO_CHECK(splitter.Next());
    unsigned char op =
        static_cast<unsigned char>(strtol(splitter.cur_token(), nullptr, 10));
    qc.AddConstraint(col, op);
  }

  PERFETTO_CHECK(splitter.Next() && splitter.cur_token_size() > 1);
  // The '+ 1' skips the letter 'O' in the current token.
  long num_order_by = strtol(splitter.cur_token() + 1, nullptr, 10);
  for (int i = 0; i < num_order_by; ++i) {
    PERFETTO_CHECK(splitter.Next());
    int col = static_cast<int>(strtol(splitter.cur_token(), nullptr, 10));
    PERFETTO_CHECK(splitter.Next());
    unsigned char desc =
        static_cast<unsigned char>(strtol(splitter.cur_token(), nullptr, 10));
    qc.AddOrderBy(col, desc);
  }

  PERFETTO_DCHECK(!splitter.Next());
  return qc;
}

}  // namespace trace_processor
}  // namespace perfetto
