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

#include "src/trace_processor/prelude/functions/sqlite3_str_split.h"

#include "src/trace_processor/sqlite/sqlite_utils.h"

namespace perfetto {
namespace trace_processor {

namespace {
constexpr char kDelimiterError[] =
    "str_split: delimiter must be a non-empty string";
constexpr char kSplitFieldIndexError[] =
    "str_split: field number must be a non-negative integer";

void sqlite_str_split(sqlite3_context* context,
                      int argc,
                      sqlite3_value** argv) {
  PERFETTO_DCHECK(argc == 3);
  if (sqlite3_value_type(argv[1]) != SQLITE_TEXT) {
    sqlite3_result_error(context, kDelimiterError, -1);
    return;
  }
  const char* delimiter =
      reinterpret_cast<const char*>(sqlite3_value_text(argv[1]));
  const size_t delimiter_len = strlen(delimiter);
  if (delimiter_len == 0) {
    sqlite3_result_error(context, kDelimiterError, -1);
    return;
  }
  if (sqlite3_value_type(argv[2]) != SQLITE_INTEGER) {
    sqlite3_result_error(context, kSplitFieldIndexError, -1);
    return;
  }
  int fld = sqlite3_value_int(argv[2]);
  if (fld < 0) {
    sqlite3_result_error(context, kSplitFieldIndexError, -1);
    return;
  }
  if (sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
    sqlite3_result_null(context);
    return;
  }
  const char* in = reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
  const char* next;
  do {
    next = strstr(in, delimiter);
    if (fld == 0) {
      int size = next != nullptr ? static_cast<int>(next - in)
                                 : static_cast<int>(strlen(in));
      sqlite3_result_text(context, in, size, sqlite_utils::kSqliteTransient);
      return;
    } else if (next == nullptr) {
      break;
    }
    in = next + delimiter_len;
    --fld;
  } while (fld >= 0);
  sqlite3_result_null(context);
}
}  // namespace

void sqlite3_str_split_init(sqlite3* db) {
  PERFETTO_CHECK(sqlite3_create_function(db, "str_split", 3,
                                         SQLITE_UTF8 | SQLITE_DETERMINISTIC,
                                         nullptr, &sqlite_str_split, nullptr,
                                         nullptr) == SQLITE_OK);
}

}  // namespace trace_processor
}  // namespace perfetto
