/*
 * Copyright (C) 2021 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/prelude/functions/create_function_internal.h"

#include "perfetto/base/status.h"
#include "perfetto/ext/base/string_view.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/util/status_macros.h"

namespace perfetto {
namespace trace_processor {

base::Status ParseFunctionName(base::StringView raw, base::StringView& out) {
  size_t function_name_end = raw.find('(');
  if (function_name_end == base::StringView::npos)
    return base::ErrStatus("unable to find bracket starting argument list");

  base::StringView function_name = raw.substr(0, function_name_end);
  if (!sql_argument::IsValidName(function_name)) {
    return base::ErrStatus("function name %s is not alphanumeric",
                           function_name.ToStdString().c_str());
  }
  out = function_name;
  return base::OkStatus();
}

base::Status ParsePrototype(base::StringView raw, Prototype& out) {
  // Examples of function prototypes:
  // ANDROID_SDK_LEVEL()
  // STARTUP_SLICE(dur_ns INT)
  // FIND_NEXT_SLICE_WITH_NAME(ts INT, name STRING)

  base::StringView function_name;
  RETURN_IF_ERROR(ParseFunctionName(raw, function_name));

  size_t function_name_end = function_name.size();
  size_t args_start = function_name_end + 1;
  size_t args_end = raw.find(')', args_start);
  if (args_end == base::StringView::npos)
    return base::ErrStatus("unable to find bracket ending argument list");

  base::StringView args_str = raw.substr(args_start, args_end - args_start);
  RETURN_IF_ERROR(sql_argument::ParseArgumentDefinitions(args_str.ToStdString(),
                                                         out.arguments));

  out.function_name = function_name.ToStdString();
  return base::OkStatus();
}

base::Status SqliteRetToStatus(sqlite3* db,
                               const std::string& function_name,
                               int ret) {
  if (ret != SQLITE_ROW && ret != SQLITE_DONE) {
    return base::ErrStatus("%s: SQLite error while executing function body: %s",
                           function_name.c_str(), sqlite3_errmsg(db));
  }
  return base::OkStatus();
}

base::Status MaybeBindArgument(sqlite3_stmt* stmt,
                               const std::string& function_name,
                               const sql_argument::ArgumentDefinition& arg,
                               sqlite3_value* value) {
  int index = sqlite3_bind_parameter_index(stmt, arg.dollar_name().c_str());

  // If the argument is not in the query, this just means its an unused
  // argument which we can just ignore.
  if (index == 0)
    return base::Status();

  int ret = sqlite3_bind_value(stmt, index, value);
  if (ret != SQLITE_OK) {
    return base::ErrStatus(
        "%s: SQLite error while binding value to argument %s: %s",
        function_name.c_str(), arg.name().c_str(),
        sqlite3_errmsg(sqlite3_db_handle(stmt)));
  }
  return base::OkStatus();
}

}  // namespace trace_processor
}  // namespace perfetto
