/*
 * 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 "src/trace_processor/ftrace_descriptors.h"
#include "src/trace_processor/sqlite_utils.h"
#include "src/trace_processor/variadic.h"

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

namespace perfetto {
namespace trace_processor {

RawTable::RawTable(sqlite3* db, const TraceStorage* storage)
    : storage_(storage) {
  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);
}

void RawTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
  Table::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();

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

  return SQLITE_OK;
}

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));

  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, write_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") {
    using P = protos::pbzero::PrintFtraceEvent;

    uint32_t arg_row = start_row + P::kBufFieldNumber - 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);
}

}  // namespace trace_processor
}  // namespace perfetto
