/*
 * Copyright (C) 2019 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.
 */

#ifndef SRC_PROFILING_SYMBOLIZER_LOCAL_SYMBOLIZER_H_
#define SRC_PROFILING_SYMBOLIZER_LOCAL_SYMBOLIZER_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/scoped_file.h"
#include "src/profiling/symbolizer/subprocess.h"
#include "src/profiling/symbolizer/symbolizer.h"

namespace perfetto {
namespace profiling {

bool ParseLlvmSymbolizerLine(const std::string& line,
                             std::string* file_name,
                             uint32_t* line_no);
std::vector<std::string> GetLines(
    std::function<int64_t(char*, size_t)> fn_read);

struct FoundBinary {
  std::string file_name;
  uint64_t load_bias;
};

class BinaryFinder {
 public:
  virtual ~BinaryFinder();
  virtual base::Optional<FoundBinary> FindBinary(
      const std::string& abspath,
      const std::string& build_id) = 0;
};

class LocalBinaryIndexer : public BinaryFinder {
 public:
  explicit LocalBinaryIndexer(std::vector<std::string> roots);

  base::Optional<FoundBinary> FindBinary(const std::string& abspath,
                                         const std::string& build_id) override;
  ~LocalBinaryIndexer() override;

 private:
  std::map<std::string, FoundBinary> buildid_to_file_;
};

class LocalBinaryFinder : public BinaryFinder {
 public:
  explicit LocalBinaryFinder(std::vector<std::string> roots);

  base::Optional<FoundBinary> FindBinary(const std::string& abspath,
                                         const std::string& build_id) override;

  ~LocalBinaryFinder() override;

 private:
  base::Optional<FoundBinary> IsCorrectFile(const std::string& symbol_file,
                                            const std::string& build_id);

  base::Optional<FoundBinary> FindBinaryInRoot(const std::string& root_str,
                                               const std::string& abspath,
                                               const std::string& build_id);

 private:
  std::vector<std::string> roots_;
  std::map<std::string, base::Optional<FoundBinary>> cache_;
};

class LLVMSymbolizerProcess {
 public:
  explicit LLVMSymbolizerProcess(const std::string& symbolizer_path);

  std::vector<SymbolizedFrame> Symbolize(const std::string& binary,
                                         uint64_t address);

 private:
  Subprocess subprocess_;
};

class LocalSymbolizer : public Symbolizer {
 public:
  LocalSymbolizer(const std::string& symbolizer_path,
                  std::unique_ptr<BinaryFinder> finder);

  explicit LocalSymbolizer(std::unique_ptr<BinaryFinder> finder);

  std::vector<std::vector<SymbolizedFrame>> Symbolize(
      const std::string& mapping_name,
      const std::string& build_id,
      uint64_t load_bias,
      const std::vector<uint64_t>& address) override;

  bool BuildIdNeedsHexConversion() override { return true; }

  ~LocalSymbolizer() override;

 private:
  LLVMSymbolizerProcess llvm_symbolizer_;
  std::unique_ptr<BinaryFinder> finder_;
};

std::unique_ptr<Symbolizer> LocalSymbolizerOrDie(
    std::vector<std::string> binary_path,
    const char* mode);

}  // namespace profiling
}  // namespace perfetto

#endif  // SRC_PROFILING_SYMBOLIZER_LOCAL_SYMBOLIZER_H_
