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

  // 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(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
