/*
 * Copyright (C) 2024 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_redaction/redact_sched_events.h"

#include "perfetto/protozero/scattered_heap_buffer.h"
#include "src/trace_processor/util/status_macros.h"
#include "src/trace_redaction/proto_util.h"

#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
#include "protos/perfetto/trace/ftrace/sched.pbzero.h"

namespace perfetto::trace_redaction {

namespace {
bool IsTrue(bool value) {
  return value;
}

// Copy a field from 'decoder' to 'message' if the field can be found. Returns
// false if the field cannot be found.
bool Passthrough(protozero::ProtoDecoder& decoder,
                 uint32_t field_id,
                 protozero::Message* message) {
  auto field = decoder.FindField(field_id);

  if (field.valid()) {
    proto_util::AppendField(field, message);
    return true;
  }

  return false;
}
}  // namespace

int64_t InternTable::Push(const char* data, size_t size) {
  std::string_view outer(data, size);

  for (size_t i = 0; i < interned_comms_.size(); ++i) {
    auto view = interned_comms_[i];

    if (view == outer) {
      return static_cast<int64_t>(i);
    }
  }

  // No room for the new string, reject the request.
  if (comms_length_ + size > comms_.size()) {
    return -1;
  }

  auto* head = comms_.data() + comms_length_;

  // Important note, the null byte is not copied.
  memcpy(head, data, size);
  comms_length_ += size;

  size_t id = interned_comms_.size();
  interned_comms_.emplace_back(head, size);

  return static_cast<int64_t>(id);
}

std::string_view InternTable::Find(size_t index) const {
  if (index < interned_comms_.size()) {
    return interned_comms_[index];
  }

  return {};
}

// Redact sched switch trace events in an ftrace event bundle:
//
//  event {
//    timestamp: 6702093744772646
//    pid: 0
//    sched_switch {
//      prev_comm: "swapper/0"
//      prev_pid: 0
//      prev_prio: 120
//      prev_state: 0
//      next_comm: "writer"
//      next_pid: 23020
//      next_prio: 96
//    }
//  }
//
// In the above message, it should be noted that "event.pid" will always be
// equal to "event.sched_switch.prev_pid".
//
// "ftrace_event_bundle_message" is the ftrace event bundle (contains a
// collection of ftrace event messages) because data in a sched_switch message
// is needed in order to know if the event should be added to the bundle.

base::Status RedactSchedEvents::Transform(const Context& context,
                                          std::string* packet) const {
  PERFETTO_DCHECK(modifier_);
  PERFETTO_DCHECK(waking_filter_);

  if (!context.timeline) {
    return base::ErrStatus("RedactSchedEvents: missing timeline.");
  }

  if (!context.package_uid.has_value()) {
    return base::ErrStatus("RedactSchedEvents: missing package uid.");
  }

  if (!packet || packet->empty()) {
    return base::ErrStatus("RedactSchedEvents: null or empty packet.");
  }

  protozero::HeapBuffered<protos::pbzero::TracePacket> message;
  protozero::ProtoDecoder decoder(*packet);

  for (auto field = decoder.ReadField(); field.valid();
       field = decoder.ReadField()) {
    if (field.id() == protos::pbzero::TracePacket::kFtraceEventsFieldNumber) {
      RETURN_IF_ERROR(
          OnFtraceEvents(context, field, message->set_ftrace_events()));
    } else {
      proto_util::AppendField(field, message.get());
    }
  }

  packet->assign(message.SerializeAsString());

  return base::OkStatus();
}

base::Status RedactSchedEvents::OnFtraceEvents(
    const Context& context,
    protozero::Field ftrace_events,
    protos::pbzero::FtraceEventBundle* message) const {
  PERFETTO_DCHECK(ftrace_events.id() ==
                  protos::pbzero::TracePacket::kFtraceEventsFieldNumber);

  protozero::ProtoDecoder decoder(ftrace_events.as_bytes());

  auto cpu =
      decoder.FindField(protos::pbzero::FtraceEventBundle::kCpuFieldNumber);
  if (!cpu.valid()) {
    return base::ErrStatus(
        "RedactSchedEvents: missing cpu in ftrace event bundle.");
  }

  for (auto field = decoder.ReadField(); field.valid();
       field = decoder.ReadField()) {
    if (field.id() == protos::pbzero::FtraceEventBundle::kEventFieldNumber) {
      RETURN_IF_ERROR(
          OnFtraceEvent(context, cpu.as_int32(), field, message->add_event()));
      continue;
    }

    if (field.id() ==
        protos::pbzero::FtraceEventBundle::kCompactSchedFieldNumber) {
      protos::pbzero::FtraceEventBundle::CompactSched::Decoder comp_sched(
          field.as_bytes());
      RETURN_IF_ERROR(OnCompSched(context, cpu.as_int32(), comp_sched,
                                  message->set_compact_sched()));
      continue;
    }

    proto_util::AppendField(field, message);
  }

  return base::OkStatus();
}

base::Status RedactSchedEvents::OnFtraceEvent(
    const Context& context,
    int32_t cpu,
    protozero::Field ftrace_event,
    protos::pbzero::FtraceEvent* message) const {
  PERFETTO_DCHECK(ftrace_event.id() ==
                  protos::pbzero::FtraceEventBundle::kEventFieldNumber);

  protozero::ProtoDecoder decoder(ftrace_event.as_bytes());

  auto ts =
      decoder.FindField(protos::pbzero::FtraceEvent::kTimestampFieldNumber);
  if (!ts.valid()) {
    return base::ErrStatus(
        "RedactSchedEvents: missing timestamp in ftrace event.");
  }

  std::string scratch_str;

  for (auto field = decoder.ReadField(); field.valid();
       field = decoder.ReadField()) {
    switch (field.id()) {
      case protos::pbzero::FtraceEvent::kSchedSwitchFieldNumber: {
        protos::pbzero::SchedSwitchFtraceEvent::Decoder sched_switch(
            field.as_bytes());
        RETURN_IF_ERROR(OnFtraceEventSwitch(context, ts.as_uint64(), cpu,
                                            sched_switch, &scratch_str,
                                            message->set_sched_switch()));
        break;
      }

      case protos::pbzero::FtraceEvent::kSchedWakingFieldNumber: {
        protos::pbzero::SchedWakingFtraceEvent::Decoder sched_waking(
            field.as_bytes());
        RETURN_IF_ERROR(OnFtraceEventWaking(
            context, ts.as_uint64(), cpu, sched_waking, &scratch_str, message));
        break;
      }

      default: {
        proto_util::AppendField(field, message);
        break;
      }
    }
  }

  return base::OkStatus();
}

base::Status RedactSchedEvents::OnFtraceEventSwitch(
    const Context& context,
    uint64_t ts,
    int32_t cpu,
    protos::pbzero::SchedSwitchFtraceEvent::Decoder& sched_switch,
    std::string* scratch_str,
    protos::pbzero::SchedSwitchFtraceEvent* message) const {
  PERFETTO_DCHECK(modifier_);
  PERFETTO_DCHECK(scratch_str);
  PERFETTO_DCHECK(message);

  std::array<bool, 7> has_fields = {
      sched_switch.has_prev_comm(), sched_switch.has_prev_pid(),
      sched_switch.has_prev_prio(), sched_switch.has_prev_state(),
      sched_switch.has_next_comm(), sched_switch.has_next_pid(),
      sched_switch.has_next_prio()};

  if (!std::all_of(has_fields.begin(), has_fields.end(), IsTrue)) {
    return base::ErrStatus(
        "RedactSchedEvents: missing required SchedSwitchFtraceEvent "
        "field.");
  }

  auto prev_pid = sched_switch.prev_pid();
  auto prev_comm = sched_switch.prev_comm();

  auto next_pid = sched_switch.next_pid();
  auto next_comm = sched_switch.next_comm();

  // There are 7 values in a sched switch message. Since 4 of the 7 can be
  // replaced, it is easier/cleaner to go value-by-value. Go in proto-defined
  // order.

  scratch_str->assign(prev_comm.data, prev_comm.size);

  modifier_->Modify(context, ts, cpu, &prev_pid, scratch_str);

  message->set_prev_comm(*scratch_str);                // FieldNumber = 1
  message->set_prev_pid(prev_pid);                     // FieldNumber = 2
  message->set_prev_prio(sched_switch.prev_prio());    // FieldNumber = 3
  message->set_prev_state(sched_switch.prev_state());  // FieldNumber = 4

  scratch_str->assign(next_comm.data, next_comm.size);

  modifier_->Modify(context, ts, cpu, &next_pid, scratch_str);

  message->set_next_comm(*scratch_str);              // FieldNumber = 5
  message->set_next_pid(next_pid);                   // FieldNumber = 6
  message->set_next_prio(sched_switch.next_prio());  // FieldNumber = 7

  return base::OkStatus();
}

// Redact sched waking trace events in a ftrace event bundle:
//
//  event {
//    timestamp: 6702093787823849
//    pid: 814                      <-- waker
//    sched_waking {
//      comm: "surfaceflinger"
//      pid: 756                    <-- target
//      prio: 97
//      success: 1
//      target_cpu: 2
//    }
//  }
base::Status RedactSchedEvents::OnFtraceEventWaking(
    const Context& context,
    uint64_t ts,
    int32_t cpu,
    protos::pbzero::SchedWakingFtraceEvent::Decoder& sched_waking,
    std::string* scratch_str,
    protos::pbzero::FtraceEvent* parent_message) const {
  PERFETTO_DCHECK(modifier_);
  PERFETTO_DCHECK(scratch_str);
  PERFETTO_DCHECK(parent_message);

  std::array<bool, 5> has_fields = {
      sched_waking.has_comm(), sched_waking.has_pid(), sched_waking.has_prio(),
      sched_waking.has_success(), sched_waking.has_target_cpu()};

  if (!std::all_of(has_fields.begin(), has_fields.end(), IsTrue)) {
    return base::ErrStatus(
        "RedactSchedEvents: missing required SchedWakingFtraceEvent "
        "field.");
  }

  auto pid = sched_waking.pid();

  if (!waking_filter_->Includes(context, ts, pid)) {
    return base::OkStatus();
  }

  auto comm = sched_waking.comm();

  // There are 5 values in a sched switch message. Since 2 of the 5 can be
  // replaced, it is easier/cleaner to go value-by-value. Go in proto-defined
  // order.

  scratch_str->assign(comm.data, comm.size);

  modifier_->Modify(context, ts, cpu, &pid, scratch_str);

  auto message = parent_message->set_sched_waking();
  message->set_comm(*scratch_str);                     // FieldNumber = 1
  message->set_pid(pid);                               // FieldNumber = 2
  message->set_prio(sched_waking.prio());              // FieldNumber = 3
  message->set_success(sched_waking.success());        // FieldNumber = 4
  message->set_target_cpu(sched_waking.target_cpu());  // FieldNumber = 5

  return base::OkStatus();
}

base::Status RedactSchedEvents::OnCompSched(
    const Context& context,
    int32_t cpu,
    protos::pbzero::FtraceEventBundle::CompactSched::Decoder& comp_sched,
    protos::pbzero::FtraceEventBundle::CompactSched* message) const {
  // Populate the intern table once; it will be used by both sched and waking.
  InternTable intern_table;

  for (auto it = comp_sched.intern_table(); it; ++it) {
    auto chars = it->as_string();
    auto index = intern_table.Push(chars.data, chars.size);

    if (index < 0) {
      return base::ErrStatus(
          "RedactSchedEvents: failed to insert string into intern "
          "table.");
    }
  }

  std::array<bool, 5> has_switch_fields = {
      comp_sched.has_switch_timestamp(),
      comp_sched.has_switch_prev_state(),
      comp_sched.has_switch_next_pid(),
      comp_sched.has_switch_next_prio(),
      comp_sched.has_switch_next_comm_index(),
  };

  if (std::any_of(has_switch_fields.begin(), has_switch_fields.end(), IsTrue)) {
    RETURN_IF_ERROR(
        OnCompSchedSwitch(context, cpu, comp_sched, &intern_table, message));
  }

  std::array<bool, 6> has_waking_fields = {
      comp_sched.has_waking_timestamp(),  comp_sched.has_waking_pid(),
      comp_sched.has_waking_target_cpu(), comp_sched.has_waking_prio(),
      comp_sched.has_waking_comm_index(), comp_sched.has_waking_common_flags(),
  };

  if (std::any_of(has_waking_fields.begin(), has_waking_fields.end(), IsTrue)) {
    RETURN_IF_ERROR(
        OnCompactSchedWaking(context, comp_sched, &intern_table, message));
  }

  // IMPORTANT: The intern table can only be added after switch and waking
  // because switch and/or waking can/will modify the intern table.
  for (auto view : intern_table.values()) {
    message->add_intern_table(view.data(), view.size());
  }

  return base::OkStatus();
}

base::Status RedactSchedEvents::OnCompSchedSwitch(
    const Context& context,
    int32_t cpu,
    protos::pbzero::FtraceEventBundle::CompactSched::Decoder& comp_sched,
    InternTable* intern_table,
    protos::pbzero::FtraceEventBundle::CompactSched* message) const {
  PERFETTO_DCHECK(modifier_);
  PERFETTO_DCHECK(message);

  std::array<bool, 6> has_fields = {
      comp_sched.has_intern_table(),
      comp_sched.has_switch_timestamp(),
      comp_sched.has_switch_prev_state(),
      comp_sched.has_switch_next_pid(),
      comp_sched.has_switch_next_prio(),
      comp_sched.has_switch_next_comm_index(),
  };

  if (!std::all_of(has_fields.begin(), has_fields.end(), IsTrue)) {
    return base::ErrStatus(
        "RedactSchedEvents: missing required FtraceEventBundle::CompactSched "
        "switch field.");
  }

  std::string scratch_str;

  protozero::PackedVarInt packed_comm;
  protozero::PackedVarInt packed_pid;

  // The first it_ts value is an absolute value, all other values are delta
  // values.
  uint64_t ts = 0;

  std::array<bool, 3> parse_errors = {false, false, false};

  auto it_ts = comp_sched.switch_timestamp(&parse_errors.at(0));
  auto it_pid = comp_sched.switch_next_pid(&parse_errors.at(1));
  auto it_comm = comp_sched.switch_next_comm_index(&parse_errors.at(2));

  while (it_ts && it_pid && it_comm) {
    ts += *it_ts;

    auto pid = *it_pid;

    auto comm_index = *it_comm;
    auto comm = intern_table->Find(comm_index);

    scratch_str.assign(comm);

    modifier_->Modify(context, ts, cpu, &pid, &scratch_str);

    auto found = intern_table->Push(scratch_str.data(), scratch_str.size());

    if (found < 0) {
      return base::ErrStatus(
          "RedactSchedEvents: failed to insert string into intern table.");
    }

    packed_comm.Append(found);
    packed_pid.Append(pid);

    ++it_ts;
    ++it_pid;
    ++it_comm;
  }

  if (std::any_of(parse_errors.begin(), parse_errors.end(), IsTrue)) {
    return base::ErrStatus(
        "RedactSchedEvents: error reading FtraceEventBundle::CompactSched.");
  }

  if (it_ts || it_pid || it_comm) {
    return base::ErrStatus(
        "RedactSchedEvents: uneven associative arrays in "
        "FtraceEventBundle::CompactSched (switch).");
  }

  message->set_switch_next_pid(packed_pid);
  message->set_switch_next_comm_index(packed_comm);

  // There's a lot of data in a compact sched message. Most of it is packed data
  // and most of the data is not going to change. To avoid unpacking, doing
  // nothing, and then packing... cheat. Find the fields and pass them as opaque
  // blobs.
  //
  // kInternTableFieldNumber:         The intern table will be modified by both
  //                                  switch events and waking events. It will
  //                                  be written elsewhere.
  //
  // kSwitchNextPidFieldNumber:       The switch pid will change during thread
  //                                  merging.
  //
  // kSwitchNextCommIndexFieldNumber: The switch comm value will change when
  //                                  clearing thread names and replaced
  //                                  during thread merging.

  auto passed_through = {
      Passthrough(comp_sched,
                  protos::pbzero::FtraceEventBundle::CompactSched::
                      kSwitchTimestampFieldNumber,
                  message),
      Passthrough(comp_sched,
                  protos::pbzero::FtraceEventBundle::CompactSched::
                      kSwitchPrevStateFieldNumber,
                  message),
      Passthrough(comp_sched,
                  protos::pbzero::FtraceEventBundle::CompactSched::
                      kSwitchNextPrioFieldNumber,
                  message)};

  if (!std::all_of(passed_through.begin(), passed_through.end(), IsTrue)) {
    return base::ErrStatus(
        "RedactSchedEvents: missing required "
        "FtraceEventBundle::CompactSched switch field.");
  }

  return base::OkStatus();
}

base::Status RedactSchedEvents::OnCompactSchedWaking(
    const Context& context,
    protos::pbzero::FtraceEventBundle::CompactSched::Decoder& compact_sched,
    InternTable* intern_table,
    protos::pbzero::FtraceEventBundle::CompactSched* compact_sched_message)
    const {
  protozero::PackedVarInt var_comm_index;
  protozero::PackedVarInt var_common_flags;
  protozero::PackedVarInt var_pid;
  protozero::PackedVarInt var_prio;
  protozero::PackedVarInt var_target_cpu;
  protozero::PackedVarInt var_timestamp;

  // Time is expressed as delta time, for example:
  //
  //         Event: A          B     C      D
  // Absolute Time: 20         30    35     41
  //                |          |     |      |
  //    Delta Time: 20         10    5      6
  //
  // When an event is removed, for example, event B, delta times are off:
  //
  //               Event:  A          *     C      D
  //       Absolute Time: 20         30    35     41
  //                       |          |     |      |
  //          Delta Time: 20          *     5      6
  //                       |                |      |
  // Effective Abs. Time: 20               25     31
  //               Error:  0               10     10
  //
  // To address this issue, delta times are added into a bucket. The bucket is
  // drained each time an event is retained. If an event is dropped, its time
  // is added to the bucket, but the bucket won't be drained until a retained
  // event drains it.
  uint64_t ts_bucket = 0;
  uint64_t ts_absolute = 0;

  std::string comm;

  std::array<bool, 7> parse_errors = {!compact_sched.has_intern_table(),
                                      false,
                                      false,
                                      false,
                                      false,
                                      false,
                                      false};

  // A note on readability, because the waking iterators are the primary focus,
  // they won't have a "waking" prefix.
  auto it_comm_index = compact_sched.waking_comm_index(&parse_errors.at(1));
  auto it_common_flags = compact_sched.waking_common_flags(&parse_errors.at(2));
  auto it_pid = compact_sched.waking_pid(&parse_errors.at(3));
  auto it_prio = compact_sched.waking_prio(&parse_errors.at(4));
  auto it_target_cpu = compact_sched.waking_target_cpu(&parse_errors.at(5));
  auto it_timestamp = compact_sched.waking_timestamp(&parse_errors.at(6));

  while (it_comm_index && it_common_flags && it_pid && it_prio &&
         it_target_cpu && it_timestamp) {
    ts_bucket += *it_timestamp;  // add time to the bucket
    ts_absolute += *it_timestamp;

    if (waking_filter_->Includes(context, ts_absolute, *it_pid)) {
      // Now that the waking event will be kept, it can be modified using the
      // same rules as switch events.
      auto pid = *it_pid;
      comm.assign(intern_table->Find(*it_comm_index));
      modifier_->Modify(context, ts_absolute, *it_target_cpu, &pid, &comm);

      auto comm_it = intern_table->Push(comm.data(), comm.size());

      var_comm_index.Append(comm_it);
      var_common_flags.Append(*it_common_flags);
      var_pid.Append(pid);
      var_prio.Append(*it_prio);
      var_target_cpu.Append(*it_target_cpu);
      var_timestamp.Append(ts_bucket);

      ts_bucket = 0;  // drain the whole bucket.
    }

    ++it_comm_index;
    ++it_common_flags;
    ++it_pid;
    ++it_prio;
    ++it_target_cpu;
    ++it_timestamp;
  }

  if (std::any_of(parse_errors.begin(), parse_errors.end(), IsTrue)) {
    return base::ErrStatus(
        "RedactSchedEvents: failed to parse FtraceEventBundle::CompactSched.");
  }

  if (it_comm_index || it_common_flags || it_pid || it_prio || it_target_cpu ||
      it_timestamp) {
    return base::ErrStatus(
        "RedactSchedEvents: uneven associative arrays in "
        "FtraceEventBundle::CompactSched (waking).");
  }

  compact_sched_message->set_waking_comm_index(var_comm_index);
  compact_sched_message->set_waking_common_flags(var_common_flags);
  compact_sched_message->set_waking_pid(var_pid);
  compact_sched_message->set_waking_prio(var_prio);
  compact_sched_message->set_waking_target_cpu(var_target_cpu);
  compact_sched_message->set_waking_timestamp(var_timestamp);

  return base::OkStatus();
}

}  // namespace perfetto::trace_redaction
