/*
 * Copyright (C) 2021 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/profiling/symbolizer/breakpad_symbolizer.h"

#include <optional>

#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/ext/base/string_writer.h"
#include "src/profiling/symbolizer/breakpad_parser.h"

namespace perfetto {
namespace profiling {

namespace {

// Returns the file path for a breakpad symbol file with the given |build_id|.
std::string MakeFilePath(const std::string& build_id,
                         const std::string& symbol_dir_path) {
  // The directory of the symbol file is stored in an environment variable.
  constexpr char kBreakpadSuffix[] = ".breakpad";
  std::string file_path;
  // Append file name to symbol directory path using |build_id| and
  // |kBreakpadSuffix|.
  file_path.append(symbol_dir_path);
// TODO: Add a path utility for perfetto to use here.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  file_path.append("\\");
#else
  file_path.append("/");
#endif
  file_path.append(build_id);
  file_path.append(kBreakpadSuffix);

  return file_path;
}

}  // namespace

BreakpadSymbolizer::BreakpadSymbolizer(const std::string& symbol_dir_path)
    : symbol_dir_path_(symbol_dir_path) {}

std::vector<std::vector<SymbolizedFrame>> BreakpadSymbolizer::Symbolize(
    const std::string&,
    const std::string& build_id,
    uint64_t,
    const std::vector<uint64_t>& address) {
  std::vector<std::vector<SymbolizedFrame>> result;
  size_t num_symbolized_frames = 0;
  result.reserve(address.size());
  std::string file_path;
  std::string raw_build_id = base::ToHex(build_id.c_str(), build_id.length());

  // Check to see if the |file_path_for_testing_| member is populated. If it is,
  // this file must be used.
  if (file_path_for_testing_.empty()) {
    file_path = MakeFilePath(raw_build_id, symbol_dir_path_).c_str();
  } else {
    file_path = file_path_for_testing_;
  }

  BreakpadParser parser(file_path);
  if (!parser.ParseFile()) {
    PERFETTO_ELOG("Failed to parse file %s.", file_path.c_str());
    PERFETTO_PLOG("Symbolized %zu of %zu frames.", num_symbolized_frames,
                  address.size());
    return result;
  }

  // Add each address's function name to the |result| vector in the same order.
  for (uint64_t addr : address) {
    SymbolizedFrame frame;
    std::optional<std::string> opt_func_name = parser.GetSymbol(addr);
    if (opt_func_name) {
      frame.function_name = *opt_func_name;
      num_symbolized_frames++;
    }
    result.push_back({std::move(frame)});
  }
  PERFETTO_PLOG("Symbolized %zu of %zu frames.", num_symbolized_frames,
                address.size());
  return result;
}

}  // namespace profiling
}  // namespace perfetto
