/*
 * 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/raw_table.h"

#include <inttypes.h>

#include "perfetto/base/compiler.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/variadic.h"

#include "protos/perfetto/trace/ftrace/binder.pbzero.h"
#include "protos/perfetto/trace/ftrace/clk.pbzero.h"
#include "protos/perfetto/trace/ftrace/filemap.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "protos/perfetto/trace/ftrace/sched.pbzero.h"
#include "protos/perfetto/trace/ftrace/workqueue.pbzero.h"

namespace perfetto {
namespace trace_processor {

RawTable::RawTable(sqlite3* db, const TraceStorage* storage)
    : storage_(storage) {
#if PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
  auto fn = [](sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    auto* thiz = static_cast<RawTable*>(sqlite3_user_data(ctx));
    thiz->ToSystrace(ctx, argc, argv);
  };
  sqlite3_create_function(db, "to_ftrace", 1,
                          SQLITE_UTF8 | SQLITE_DETERMINISTIC, this, fn, nullptr,
                          nullptr);
#else   // PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
  base::ignore_result(db);
#endif  // PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
}

void RawTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  SqliteTable::Register<RawTable>(db, storage, "raw");
}

StorageSchema RawTable::CreateStorageSchema() {
  const auto& raw = storage_->raw_events();
  return StorageSchema::Builder()
      .AddGenericNumericColumn("id", RowIdAccessor(TableId::kRawEvents))
      .AddOrderedNumericColumn("ts", &raw.timestamps())
      .AddStringColumn("name", &raw.name_ids(), &storage_->string_pool())
      .AddNumericColumn("cpu", &raw.cpus())
      .AddNumericColumn("utid", &raw.utids())
      .AddNumericColumn("arg_set_id", &raw.arg_set_ids())
      .Build({"name", "ts"});
}

uint32_t RawTable::RowCount() {
  return static_cast<uint32_t>(storage_->raw_events().raw_event_count());
}

int RawTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
  info->estimated_cost = RowCount();
  info->sqlite_omit_order_by = true;

  // Only the string columns are handled by SQLite
  size_t name_index = schema().ColumnIndexFromName("name");
  for (size_t i = 0; i < qc.constraints().size(); i++) {
    info->sqlite_omit_constraint[i] =
        qc.constraints()[i].column != static_cast<int>(name_index);
  }

  return SQLITE_OK;
}

#if PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)
void RawTable::FormatSystraceArgs(NullTermStringView event_name,
                                  ArgSetId arg_set_id,
                                  base::StringWriter* writer) {
  const auto& set_ids = storage_->args().set_ids();
  auto lb = std::lower_bound(set_ids.begin(), set_ids.end(), arg_set_id);
  auto ub = std::find(lb, set_ids.end(), arg_set_id + 1);

  auto start_row = static_cast<uint32_t>(std::distance(set_ids.begin(), lb));
  auto end_row = static_cast<uint32_t>(std::distance(set_ids.begin(), ub));
  using ValueWriter = std::function<void(const Variadic&)>;
  auto write_value = [this, writer](const Variadic& value) {
    switch (value.type) {
      case Variadic::kInt:
        writer->AppendInt(value.int_value);
        break;
      case Variadic::kUint:
        writer->AppendUnsignedInt(value.uint_value);
        break;
      case Variadic::kString: {
        const auto& str = storage_->GetString(value.string_value);
        writer->AppendString(str.c_str(), str.size());
        break;
      }
      case Variadic::kReal:
        writer->AppendDouble(value.real_value);
        break;
      case Variadic::kPointer:
        writer->AppendUnsignedInt(value.pointer_value);
        break;
      case Variadic::kBool:
        writer->AppendBool(value.bool_value);
        break;
      case Variadic::kJson: {
        const auto& str = storage_->GetString(value.json_value);
        writer->AppendString(str.c_str(), str.size());
        break;
      }
    }
  };
  auto write_value_at_index = [this, start_row](uint32_t arg_idx,
                                                ValueWriter value_fn) {
    value_fn(storage_->args().arg_values()[start_row + arg_idx]);
  };
  auto write_arg = [this, writer, start_row](uint32_t arg_idx,
                                             ValueWriter value_fn) {
    uint32_t arg_row = start_row + arg_idx;
    const auto& args = storage_->args();
    const auto& key = storage_->GetString(args.keys()[arg_row]);
    const auto& value = args.arg_values()[arg_row];

    writer->AppendChar(' ');
    writer->AppendString(key.c_str(), key.size());
    writer->AppendChar('=');
    value_fn(value);
  };

  if (event_name == "sched_switch") {
    using SS = protos::pbzero::SchedSwitchFtraceEvent;
    write_arg(SS::kPrevCommFieldNumber - 1, write_value);
    write_arg(SS::kPrevPidFieldNumber - 1, write_value);
    write_arg(SS::kPrevPrioFieldNumber - 1, write_value);
    write_arg(SS::kPrevStateFieldNumber - 1, [writer](const Variadic& value) {
      PERFETTO_DCHECK(value.type == Variadic::Type::kInt);
      auto state = static_cast<uint16_t>(value.int_value);
      writer->AppendString(ftrace_utils::TaskState(state).ToString('|').data());
    });
    writer->AppendLiteral(" ==>");
    write_arg(SS::kNextCommFieldNumber - 1, write_value);
    write_arg(SS::kNextPidFieldNumber - 1, write_value);
    write_arg(SS::kNextPrioFieldNumber - 1, write_value);
    return;
  } else if (event_name == "sched_wakeup") {
    using SW = protos::pbzero::SchedWakeupFtraceEvent;
    write_arg(SW::kCommFieldNumber - 1, write_value);
    write_arg(SW::kPidFieldNumber - 1, write_value);
    write_arg(SW::kPrioFieldNumber - 1, write_value);
    write_arg(SW::kTargetCpuFieldNumber - 1, [writer](const Variadic& value) {
      PERFETTO_DCHECK(value.type == Variadic::Type::kInt);
      writer->AppendPaddedInt<'0', 3>(value.int_value);
    });
    return;
  } else if (event_name == "clock_set_rate") {
    // TODO(lalitm): this is a big hack but the best way to do this now.
    // Doing this requires overhauling how we deal with args by pushing them all
    // to an array and then reading back from that array.

    // We use the string "todo" as the name to stay consistent with old
    // trace_to_text print code.
    writer->AppendString(" todo");
    write_arg(0 /* state */, write_value);
    write_arg(1 /* cpu_id */, write_value);
    return;
  } else if (event_name == "clk_set_rate") {
    using CSR = protos::pbzero::ClkSetRateFtraceEvent;
    writer->AppendLiteral(" ");
    write_value_at_index(CSR::kNameFieldNumber - 1, write_value);
    writer->AppendLiteral(" ");
    write_value_at_index(CSR::kRateFieldNumber - 1, write_value);
    return;
  } else if (event_name == "binder_transaction") {
    using BT = protos::pbzero::BinderTransactionFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BT::kDebugIdFieldNumber - 1, write_value);
    writer->AppendString(" dest_node=");
    write_value_at_index(BT::kTargetNodeFieldNumber - 1, write_value);
    writer->AppendString(" dest_proc=");
    write_value_at_index(BT::kToProcFieldNumber - 1, write_value);
    writer->AppendString(" dest_thread=");
    write_value_at_index(BT::kToThreadFieldNumber - 1, write_value);
    write_arg(BT::kReplyFieldNumber - 1, write_value);
    writer->AppendString(" flags=0x");
    write_value_at_index(
        BT::kFlagsFieldNumber - 1, [writer](const Variadic& value) {
          PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
          writer->AppendHexInt(value.uint_value);
        });
    writer->AppendString(" code=0x");
    write_value_at_index(
        BT::kCodeFieldNumber - 1, [writer](const Variadic& value) {
          PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
          writer->AppendHexInt(value.uint_value);
        });
    return;
  } else if (event_name == "binder_transaction_alloc_buf") {
    using BTAB = protos::pbzero::BinderTransactionAllocBufFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BTAB::kDebugIdFieldNumber - 1, write_value);
    write_arg(BTAB::kDataSizeFieldNumber - 1, write_value);
    write_arg(BTAB::kOffsetsSizeFieldNumber - 1, write_value);
    return;
  } else if (event_name == "binder_transaction_received") {
    using BTR = protos::pbzero::BinderTransactionReceivedFtraceEvent;
    writer->AppendString(" transaction=");
    write_value_at_index(BTR::kDebugIdFieldNumber - 1, write_value);
    return;
  } else if (event_name == "mm_filemap_add_to_page_cache") {
    using MFA = protos::pbzero::MmFilemapAddToPageCacheFtraceEvent;
    writer->AppendString(" dev ");
    write_value_at_index(MFA::kSDevFieldNumber - 1,
                         [writer](const Variadic& value) {
                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
                           writer->AppendUnsignedInt(value.uint_value >> 20);
                         });
    writer->AppendString(":");
    write_value_at_index(
        MFA::kSDevFieldNumber - 1, [writer](const Variadic& value) {
          PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
          writer->AppendUnsignedInt(value.uint_value & ((1 << 20) - 1));
        });
    writer->AppendString(" ino ");
    write_value_at_index(MFA::kIInoFieldNumber - 1,
                         [writer](const Variadic& value) {
                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
                           writer->AppendHexInt(value.uint_value);
                         });
    writer->AppendString(" page=0000000000000000");
    writer->AppendString(" pfn=");
    write_value_at_index(MFA::kPfnFieldNumber - 1, write_value);
    writer->AppendString(" ofs=");
    write_value_at_index(MFA::kIndexFieldNumber - 1,
                         [writer](const Variadic& value) {
                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
                           writer->AppendUnsignedInt(value.uint_value << 12);
                         });
    return;
  } else if (event_name == "print") {
    // 'ip' may be the first field or it may be dropped. We only care
    // about the 'buf' field which will always appear last.
    uint32_t arg_row = end_row - 1;
    const auto& args = storage_->args();
    const auto& value = args.arg_values()[arg_row];
    const auto& str = storage_->GetString(value.string_value);
    // If the last character is a newline in a print, just drop it.
    auto chars_to_print = !str.empty() && str.c_str()[str.size() - 1] == '\n'
                              ? str.size() - 1
                              : str.size();
    writer->AppendChar(' ');
    writer->AppendString(str.c_str(), chars_to_print);
    return;
  } else if (event_name == "sched_blocked_reason") {
    using SBR = protos::pbzero::SchedBlockedReasonFtraceEvent;
    write_arg(SBR::kPidFieldNumber - 1, write_value);
    write_arg(SBR::kIoWaitFieldNumber - 1, write_value);
    write_arg(SBR::kCallerFieldNumber - 1, [writer](const Variadic& value) {
      PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
      writer->AppendHexInt(value.uint_value);
    });
    return;
  } else if (event_name == "workqueue_activate_work") {
    using WAW = protos::pbzero::WorkqueueActivateWorkFtraceEvent;
    writer->AppendString(" work struct ");
    write_value_at_index(WAW::kWorkFieldNumber - 1,
                         [writer](const Variadic& value) {
                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
                           writer->AppendHexInt(value.uint_value);
                         });
    return;
  } else if (event_name == "workqueue_execute_start") {
    using WES = protos::pbzero::WorkqueueExecuteStartFtraceEvent;
    writer->AppendString(" work struct ");
    write_value_at_index(WES::kWorkFieldNumber - 1,
                         [writer](const Variadic& value) {
                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
                           writer->AppendHexInt(value.uint_value);
                         });
    writer->AppendString(": function ");
    write_value_at_index(WES::kFunctionFieldNumber - 1,
                         [writer](const Variadic& value) {
                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
                           writer->AppendHexInt(value.uint_value);
                         });
    return;
  } else if (event_name == "workqueue_execute_end") {
    using WE = protos::pbzero::WorkqueueExecuteEndFtraceEvent;
    writer->AppendString(" work struct ");
    write_value_at_index(WE::kWorkFieldNumber - 1,
                         [writer](const Variadic& value) {
                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
                           writer->AppendHexInt(value.uint_value);
                         });
    return;
  } else if (event_name == "workqueue_queue_work") {
    using WQW = protos::pbzero::WorkqueueQueueWorkFtraceEvent;
    writer->AppendString(" work struct=");
    write_value_at_index(WQW::kWorkFieldNumber - 1,
                         [writer](const Variadic& value) {
                           PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
                           writer->AppendHexInt(value.uint_value);
                         });
    write_arg(WQW::kFunctionFieldNumber - 1, [writer](const Variadic& value) {
      PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
      writer->AppendHexInt(value.uint_value);
    });
    write_arg(WQW::kWorkqueueFieldNumber - 1, [writer](const Variadic& value) {
      PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
      writer->AppendHexInt(value.uint_value);
    });
    write_value_at_index(WQW::kReqCpuFieldNumber - 1, write_value);
    write_value_at_index(WQW::kCpuFieldNumber - 1, write_value);
    return;
  }

  uint32_t arg = 0;
  for (auto it = lb; it != ub; it++) {
    write_arg(arg++, write_value);
  }
}

void RawTable::ToSystrace(sqlite3_context* ctx,
                          int argc,
                          sqlite3_value** argv) {
  if (argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_INTEGER) {
    sqlite3_result_error(ctx, "Usage: to_ftrace(id)", -1);
    return;
  }
  RowId row_id = sqlite3_value_int64(argv[0]);
  auto pair = TraceStorage::ParseRowId(row_id);
  PERFETTO_DCHECK(pair.first == TableId::kRawEvents);
  auto row = pair.second;

  const auto& raw_evts = storage_->raw_events();

  UniqueTid utid = raw_evts.utids()[row];
  const auto& thread = storage_->GetThread(utid);
  uint32_t tgid = 0;
  if (thread.upid.has_value()) {
    tgid = storage_->GetProcess(thread.upid.value()).pid;
  }
  const auto& name = storage_->GetString(thread.name_id);

  char line[4096];
  base::StringWriter writer(line, sizeof(line));

  ftrace_utils::FormatSystracePrefix(raw_evts.timestamps()[row],
                                     raw_evts.cpus()[row], thread.tid, tgid,
                                     base::StringView(name), &writer);

  const auto& event_name = storage_->GetString(raw_evts.name_ids()[row]);
  writer.AppendChar(' ');
  if (event_name == "print") {
    writer.AppendString("tracing_mark_write");
  } else {
    writer.AppendString(event_name.c_str(), event_name.size());
  }
  writer.AppendChar(':');

  FormatSystraceArgs(event_name, raw_evts.arg_set_ids()[row], &writer);
  sqlite3_result_text(ctx, writer.CreateStringCopy(), -1, free);
}
#endif  // PERFETTO_BUILDFLAG(PERFETTO_TP_FTRACE)

}  // namespace trace_processor
}  // namespace perfetto
