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

#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
#include "src/trace_processor/importers/common/args_translation_table.h"

namespace perfetto {
namespace trace_processor {

namespace {

// The raw symbol name is namespace::Interface::Method_Sym::IPCStableHash.
// We want to return namespace::Interface::Method.
std::string ExtractMojoMethod(const std::string& method_symbol) {
  // The symbol ends with "()" for some platforms, but not for all of them.
  std::string without_sym_suffix = base::StripSuffix(method_symbol, "()");
  // This suffix is platform-independent, it's coming from Chromium code.
  // https://source.chromium.org/chromium/chromium/src/+/main:mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl;l=66;drc=9d9e6f5ce548ecf228aed711f55b11c7ea8bdb55
  constexpr char kSymSuffix[] = "_Sym::IPCStableHash";
  return base::StripSuffix(without_sym_suffix, kSymSuffix);
}

// The raw symbol name is namespace::Interface::Method_Sym::IPCStableHash.
// We want to return namespace.Interface (for historical compatibility).
std::string ExtractMojoInterfaceTag(const std::string& method_symbol) {
  auto parts = base::SplitString(method_symbol, "::");
  // If we have too few parts, return the original string as is to simplify
  // debugging.
  if (parts.size() <= 2) {
    return method_symbol;
  }
  // Remove Method_Sym and IPCStableHash parts.
  parts.erase(parts.end() - 2, parts.end());
  return base::Join(parts, ".");
}

}  // namespace

ArgsTranslationTable::ArgsTranslationTable(TraceStorage* storage)
    : storage_(storage),
      interned_chrome_histogram_hash_key_(
          storage->InternString(kChromeHistogramHashKey)),
      interned_chrome_histogram_name_key_(
          storage->InternString(kChromeHistogramNameKey)),
      interned_chrome_user_event_hash_key_(
          storage->InternString(kChromeUserEventHashKey)),
      interned_chrome_user_event_action_key_(
          storage->InternString(kChromeUserEventActionKey)),
      interned_chrome_performance_mark_site_hash_key_(
          storage->InternString(kChromePerformanceMarkSiteHashKey)),
      interned_chrome_performance_mark_site_key_(
          storage->InternString(kChromePerformanceMarkSiteKey)),
      interned_chrome_performance_mark_mark_hash_key_(
          storage->InternString(kChromePerformanceMarkMarkHashKey)),
      interned_chrome_performance_mark_mark_key_(
          storage->InternString(kChromePerformanceMarkMarkKey)),
      interned_mojo_method_mapping_id_(
          storage->InternString(kMojoMethodMappingIdKey)),
      interned_mojo_method_rel_pc_(storage->InternString(kMojoMethodRelPcKey)),
      interned_mojo_method_name_(storage->InternString(kMojoMethodNameKey)),
      interned_mojo_interface_tag_(storage->InternString(kMojoIntefaceTagKey)),
      interned_obfuscated_view_dump_class_name_flat_key_(
          storage->InternString(kObfuscatedViewDumpClassNameFlatKey)) {}

bool ArgsTranslationTable::NeedsTranslation(StringId flat_key_id,
                                            StringId key_id,
                                            Variadic::Type type) const {
  return KeyIdAndTypeToEnum(flat_key_id, key_id, type).has_value();
}

void ArgsTranslationTable::TranslateArgs(
    const ArgsTracker::CompactArgSet& arg_set,
    ArgsTracker::BoundInserter& inserter) const {
  std::optional<uint64_t> mapping_id;
  std::optional<uint64_t> rel_pc;

  for (const auto& arg : arg_set) {
    const auto key_type =
        KeyIdAndTypeToEnum(arg.flat_key, arg.key, arg.value.type);
    if (!key_type.has_value()) {
      inserter.AddArg(arg.flat_key, arg.key, arg.value, arg.update_policy);
      continue;
    }

    switch (*key_type) {
      case KeyType::kChromeHistogramHash: {
        inserter.AddArg(interned_chrome_histogram_hash_key_, arg.value);
        const std::optional<base::StringView> translated_value =
            TranslateChromeHistogramHash(arg.value.uint_value);
        if (translated_value) {
          inserter.AddArg(
              interned_chrome_histogram_name_key_,
              Variadic::String(storage_->InternString(*translated_value)));
        }
        break;
      }
      case KeyType::kChromeUserEventHash: {
        inserter.AddArg(interned_chrome_user_event_hash_key_, arg.value);
        const std::optional<base::StringView> translated_value =
            TranslateChromeUserEventHash(arg.value.uint_value);
        if (translated_value) {
          inserter.AddArg(
              interned_chrome_user_event_action_key_,
              Variadic::String(storage_->InternString(*translated_value)));
        }
        break;
      }
      case KeyType::kChromePerformanceMarkMarkHash: {
        inserter.AddArg(interned_chrome_performance_mark_mark_hash_key_,
                        arg.value);
        const std::optional<base::StringView> translated_value =
            TranslateChromePerformanceMarkMarkHash(arg.value.uint_value);
        if (translated_value) {
          inserter.AddArg(
              interned_chrome_performance_mark_mark_key_,
              Variadic::String(storage_->InternString(*translated_value)));
        }
        break;
      }
      case KeyType::kChromePerformanceMarkSiteHash: {
        inserter.AddArg(interned_chrome_performance_mark_site_hash_key_,
                        arg.value);
        const std::optional<base::StringView> translated_value =
            TranslateChromePerformanceMarkSiteHash(arg.value.uint_value);
        if (translated_value) {
          inserter.AddArg(
              interned_chrome_performance_mark_site_key_,
              Variadic::String(storage_->InternString(*translated_value)));
        }
        break;
      }
      case KeyType::kClassName: {
        const std::optional<StringId> translated_class_name =
            TranslateClassName(arg.value.string_value);
        if (translated_class_name) {
          inserter.AddArg(arg.flat_key, arg.key,
                          Variadic::String(*translated_class_name));
        } else {
          inserter.AddArg(arg.flat_key, arg.key, arg.value);
        }
        break;
      }
      case KeyType::kMojoMethodMappingId: {
        mapping_id = arg.value.uint_value;
        break;
      }
      case KeyType::kMojoMethodRelPc: {
        rel_pc = arg.value.uint_value;
        break;
      }
    }
  }
  EmitMojoMethodLocation(mapping_id, rel_pc, inserter);
}

std::optional<ArgsTranslationTable::KeyType>
ArgsTranslationTable::KeyIdAndTypeToEnum(StringId flat_key_id,
                                         StringId key_id,
                                         Variadic::Type type) const {
  if (type == Variadic::Type::kUint) {
    if (key_id == interned_chrome_histogram_hash_key_) {
      return KeyType::kChromeHistogramHash;
    }
    if (key_id == interned_chrome_user_event_hash_key_) {
      return KeyType::kChromeUserEventHash;
    }
    if (key_id == interned_chrome_performance_mark_mark_hash_key_) {
      return KeyType::kChromePerformanceMarkMarkHash;
    }
    if (key_id == interned_chrome_performance_mark_site_hash_key_) {
      return KeyType::kChromePerformanceMarkSiteHash;
    }
    if (key_id == interned_mojo_method_mapping_id_) {
      return KeyType::kMojoMethodMappingId;
    }
    if (key_id == interned_mojo_method_rel_pc_) {
      return KeyType::kMojoMethodRelPc;
    }
  } else if (type == Variadic::Type::kString) {
    if (flat_key_id == interned_obfuscated_view_dump_class_name_flat_key_) {
      return KeyType::kClassName;
    }
  }
  return std::nullopt;
}

std::optional<base::StringView>
ArgsTranslationTable::TranslateChromeHistogramHash(uint64_t hash) const {
  auto* value = chrome_histogram_hash_to_name_.Find(hash);
  if (!value) {
    return std::nullopt;
  }
  return base::StringView(*value);
}

std::optional<base::StringView>
ArgsTranslationTable::TranslateChromeUserEventHash(uint64_t hash) const {
  auto* value = chrome_user_event_hash_to_action_.Find(hash);
  if (!value) {
    return std::nullopt;
  }
  return base::StringView(*value);
}

std::optional<base::StringView>
ArgsTranslationTable::TranslateChromePerformanceMarkSiteHash(
    uint64_t hash) const {
  auto* value = chrome_performance_mark_site_hash_to_name_.Find(hash);
  if (!value) {
    return std::nullopt;
  }
  return base::StringView(*value);
}

std::optional<base::StringView>
ArgsTranslationTable::TranslateChromePerformanceMarkMarkHash(
    uint64_t hash) const {
  auto* value = chrome_performance_mark_mark_hash_to_name_.Find(hash);
  if (!value) {
    return std::nullopt;
  }
  return base::StringView(*value);
}

std::optional<ArgsTranslationTable::SourceLocation>
ArgsTranslationTable::TranslateNativeSymbol(MappingId mapping_id,
                                            uint64_t rel_pc) const {
  auto loc =
      native_symbol_to_location_.Find(std::make_pair(mapping_id, rel_pc));
  if (!loc) {
    return std::nullopt;
  }
  return *loc;
}

std::optional<StringId> ArgsTranslationTable::TranslateClassName(
    StringId obfuscated_class_name_id) const {
  return deobfuscation_mapping_table_.TranslateClass(obfuscated_class_name_id);
}

void ArgsTranslationTable::EmitMojoMethodLocation(
    std::optional<uint64_t> mapping_id,
    std::optional<uint64_t> rel_pc,
    ArgsTracker::BoundInserter& inserter) const {
  if (!mapping_id || !rel_pc) {
    return;
  }
  const MappingId row_id(static_cast<uint32_t>(*mapping_id));
  const auto loc = TranslateNativeSymbol(row_id, *rel_pc);
  if (loc) {
    inserter.AddArg(interned_mojo_method_name_,
                    Variadic::String(storage_->InternString(base::StringView(
                        ExtractMojoMethod((loc->function_name))))));
    inserter.AddArg(interned_mojo_interface_tag_,
                    Variadic::String(storage_->InternString(base::StringView(
                        ExtractMojoInterfaceTag(loc->function_name)))),
                    // If the trace already has interface tag as a raw string
                    // (older Chromium versions, local traces, and so on), use
                    // the raw string.
                    GlobalArgsTracker::UpdatePolicy::kSkipIfExists);
  } else {
    // Could not find the corresponding source location. Let's emit raw arg
    // values so that the data doesn't silently go missing.
    inserter.AddArg(interned_mojo_method_mapping_id_,
                    Variadic::UnsignedInteger(*mapping_id));
    inserter.AddArg(interned_mojo_method_rel_pc_,
                    Variadic::UnsignedInteger(*rel_pc));
  }
}

}  // namespace trace_processor
}  // namespace perfetto
