/*
 * Copyright (C) 2022 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/importers/proto/statsd_module.h"

#include "perfetto/ext/base/string_utils.h"
#include "protos/perfetto/trace/statsd/statsd_atom.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
#include "src/trace_processor/importers/common/async_track_set_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/sorter/trace_sorter.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/util/descriptors.h"

#include "src/trace_processor/importers/proto/atoms.descriptor.h"

namespace perfetto {
namespace trace_processor {
namespace {

constexpr const char* kAtomProtoName = ".android.os.statsd.Atom";

using BoundInserter = ArgsTracker::BoundInserter;

class InserterDelegate : public util::ProtoToArgsParser::Delegate {
 public:
  InserterDelegate(BoundInserter& inserter, TraceStorage& storage)
      : inserter_(inserter), storage_(storage) {}
  ~InserterDelegate() override = default;

  using Key = util::ProtoToArgsParser::Key;

  void AddInteger(const Key& key, int64_t value) override {
    StringId flat_key_id =
        storage_.InternString(base::StringView(key.flat_key));
    StringId key_id = storage_.InternString(base::StringView(key.key));
    Variadic variadic_val = Variadic::Integer(value);
    inserter_.AddArg(flat_key_id, key_id, variadic_val);
  }

  void AddUnsignedInteger(const Key& key, uint64_t value) override {
    StringId flat_key_id =
        storage_.InternString(base::StringView(key.flat_key));
    StringId key_id = storage_.InternString(base::StringView(key.key));
    Variadic variadic_val = Variadic::UnsignedInteger(value);
    inserter_.AddArg(flat_key_id, key_id, variadic_val);
  }

  void AddString(const Key& key, const protozero::ConstChars& value) override {
    StringId flat_key_id =
        storage_.InternString(base::StringView(key.flat_key));
    StringId key_id = storage_.InternString(base::StringView(key.key));
    Variadic variadic_val = Variadic::String(storage_.InternString(value));
    inserter_.AddArg(flat_key_id, key_id, variadic_val);
  }

  void AddString(const Key& key, const std::string& value) override {
    StringId flat_key_id =
        storage_.InternString(base::StringView(key.flat_key));
    StringId key_id = storage_.InternString(base::StringView(key.key));
    Variadic variadic_val =
        Variadic::String(storage_.InternString(base::StringView(value)));
    inserter_.AddArg(flat_key_id, key_id, variadic_val);
  }

  void AddDouble(const Key& key, double value) override {
    StringId flat_key_id =
        storage_.InternString(base::StringView(key.flat_key));
    StringId key_id = storage_.InternString(base::StringView(key.key));
    Variadic variadic_val = Variadic::Real(value);
    inserter_.AddArg(flat_key_id, key_id, variadic_val);
  }

  void AddPointer(const Key& key, const void* value) override {
    StringId flat_key_id =
        storage_.InternString(base::StringView(key.flat_key));
    StringId key_id = storage_.InternString(base::StringView(key.key));
    Variadic variadic_val =
        Variadic::Pointer(reinterpret_cast<uintptr_t>(value));
    inserter_.AddArg(flat_key_id, key_id, variadic_val);
  }

  void AddBoolean(const Key& key, bool value) override {
    StringId flat_key_id =
        storage_.InternString(base::StringView(key.flat_key));
    StringId key_id = storage_.InternString(base::StringView(key.key));
    Variadic variadic_val = Variadic::Boolean(value);
    inserter_.AddArg(flat_key_id, key_id, variadic_val);
  }

  bool AddJson(const Key&, const protozero::ConstChars&) override {
    PERFETTO_FATAL("Unexpected JSON value when parsing statsd data");
  }

  void AddNull(const Key& key) override {
    StringId flat_key_id =
        storage_.InternString(base::StringView(key.flat_key));
    StringId key_id = storage_.InternString(base::StringView(key.key));
    Variadic variadic_val = Variadic::Null();
    inserter_.AddArg(flat_key_id, key_id, variadic_val);
  }

  size_t GetArrayEntryIndex(const std::string& array_key) override {
    base::ignore_result(array_key);
    return 0;
  }

  size_t IncrementArrayEntryIndex(const std::string& array_key) override {
    base::ignore_result(array_key);
    return 0;
  }

  PacketSequenceStateGeneration* seq_state() override { return nullptr; }

 protected:
  InternedMessageView* GetInternedMessageView(uint32_t field_id,
                                              uint64_t iid) override {
    base::ignore_result(field_id);
    base::ignore_result(iid);
    return nullptr;
  }

 private:
  BoundInserter& inserter_;
  TraceStorage& storage_;
};

}  // namespace

using perfetto::protos::pbzero::TracePacket;

PoolAndDescriptor::PoolAndDescriptor(const uint8_t* data,
                                     size_t size,
                                     const char* name) {
  pool_.AddFromFileDescriptorSet(data, size);
  std::optional<uint32_t> opt_idx = pool_.FindDescriptorIdx(name);
  if (opt_idx.has_value()) {
    descriptor_ = &pool_.descriptors()[opt_idx.value()];
  }
}

PoolAndDescriptor::~PoolAndDescriptor() = default;

StatsdModule::StatsdModule(TraceProcessorContext* context)
    : context_(context),
      pool_(kAtomsDescriptor.data(), kAtomsDescriptor.size(), kAtomProtoName),
      args_parser_(*(pool_.pool())) {
  RegisterForField(TracePacket::kStatsdAtomFieldNumber, context);
}

StatsdModule::~StatsdModule() = default;

void StatsdModule::ParseTracePacketData(const TracePacket::Decoder& decoder,
                                        int64_t ts,
                                        const TracePacketData&,
                                        uint32_t field_id) {
  if (field_id != TracePacket::kStatsdAtomFieldNumber) {
    return;
  }
  const auto& atoms_wrapper =
      protos::pbzero::StatsdAtom::Decoder(decoder.statsd_atom());
  for (auto it = atoms_wrapper.atom(); it; ++it) {
    ParseAtom(ts, *it);
  }
}

void StatsdModule::ParseAtom(int64_t ts, protozero::ConstBytes nested_bytes) {
  // nested_bytes is an Atom proto. We (deliberately) don't generate
  // decoding code for every kind of atom (or the parent Atom proto)
  // and instead use the descriptor to parse the args/name.

  // Atom is a giant oneof of all the possible 'kinds' of atom so here
  // we use the protozero decoder implementation to grab the first
  // field id which we we use to look up the field name:
  protozero::ProtoDecoder nested_decoder(nested_bytes);
  protozero::Field field = nested_decoder.ReadField();
  uint32_t nested_field_id = 0;
  if (field.valid()) {
    nested_field_id = field.id();
  }
  StringId atom_name = GetAtomName(nested_field_id);

  AsyncTrackSetTracker::TrackSetId track_set = InternAsyncTrackSetId();
  TrackId track = context_->async_track_set_tracker->Scoped(track_set, ts, 0);
  std::optional<SliceId> opt_slice =
      context_->slice_tracker->Scoped(ts, track, kNullStringId, atom_name, 0);
  if (!opt_slice) {
    return;
  }
  SliceId slice = opt_slice.value();
  auto inserter = context_->args_tracker->AddArgsTo(slice);
  InserterDelegate delgate(inserter, *context_->storage.get());
  args_parser_.ParseMessage(nested_bytes, kAtomProtoName,
                            nullptr /* parse all fields */, delgate);
}

StringId StatsdModule::GetAtomName(uint32_t atom_field_id) {
  StringId* cached_name = atom_names_.Find(atom_field_id);
  if (cached_name == nullptr) {
    if (pool_.descriptor() == nullptr) {
      return context_->storage->InternString("Could not load atom descriptor");
    }

    const auto& fields = pool_.descriptor()->fields();
    const auto& field_it = fields.find(atom_field_id);
    if (field_it == fields.end()) {
      return context_->storage->InternString("Unknown atom");
    }

    const FieldDescriptor& field = field_it->second;
    StringId name =
        context_->storage->InternString(base::StringView(field.name()));
    atom_names_[atom_field_id] = name;
    return name;
  }
  return *cached_name;
}

AsyncTrackSetTracker::TrackSetId StatsdModule::InternAsyncTrackSetId() {
  if (!track_set_id_) {
    StringId name = context_->storage->InternString("Statsd Atoms");
    track_set_id_ =
        context_->async_track_set_tracker->InternGlobalTrackSet(name);
  }
  return track_set_id_.value();
}

}  // namespace trace_processor
}  // namespace perfetto
