/*
 * Copyright (C) 2018 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 "perfetto/ext/traceconv/traceconv.h"

#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <optional>
#include <string>
#include <vector>

#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/version.h"
#include "perfetto/profiling/pprof_builder.h"
#include "src/protozero/text_to_proto/text_to_proto.h"
#include "src/traceconv/android_extension.descriptor.h"
#include "src/traceconv/deobfuscate_profile.h"
#include "src/traceconv/symbolize_profile.h"
#include "src/traceconv/trace.descriptor.h"
#include "src/traceconv/trace_to_bundle.h"
#include "src/traceconv/trace_to_firefox.h"
#include "src/traceconv/trace_to_json.h"
#include "src/traceconv/trace_to_profile.h"
#include "src/traceconv/trace_to_systrace.h"
#include "src/traceconv/trace_to_text.h"
#include "src/traceconv/trace_unpack.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <fcntl.h>
#include <io.h>
#else
#include <unistd.h>
#endif

namespace perfetto::traceconv {
namespace {

int Usage(const char* argv0) {
  fprintf(stderr, R"(
Trace format conversion tool.
Usage: %s MODE [OPTIONS] [input_file] [output_file]

CONVERSION MODES AND THEIR SUPPORTED OPTIONS:

 systrace                             Converts to systrace HTML format
   --truncate [start|end]             Truncates trace to keep start or end
   --full-sort                        Forces full trace sorting

 json                                 Converts to Chrome JSON format
   --truncate [start|end]             Truncates trace to keep start or end
   --full-sort                        Forces full trace sorting

 ctrace                               Converts to compressed systrace format
   --truncate [start|end]             Truncates trace to keep start or end
   --full-sort                        Forces full trace sorting

 text                                 Converts to human-readable text format
   --skip-unknown                     Skip unknown fields when converting to text

 profile                              Converts profile data to pprof format
                                      (default: auto-detect profile type)
   --alloc                            Convert only the allocator profile
   --perf                             Convert only the perf profile
   --java-heap                        Convert only the heap graph profile
   --no-annotations                   Don't add derived annotations to frames
   --timestamps T1,T2,...             Generate profiles for specific timestamps
   --pid PID                          Generate profiles for specific process
   --output-dir DIR                   Output directory for profiles (default: random tmp)

 java_heap_profile                    Legacy alias for "profile --java-heap"

 symbolize                            Symbolizes addresses in profiles
   (no additional options)

 deobfuscate                          Deobfuscates obfuscated profiles
   (no additional options)

 firefox                              Converts to Firefox profiler format
   (no additional options)

 decompress_packets                   Decompresses compressed trace packets
   (no additional options)

 bundle                               Creates bundle with trace + debug data
                                      (outputs TAR with symbols/deobfuscation mappings)
                                      Requires input and output file paths (no stdin/stdout)
   --symbol-paths PATH1,PATH2,...     Additional paths to search for symbols
                                      (beyond automatic discovery)
   --no-auto-symbol-paths             Disable automatic symbol path discovery
   --proguard-map [pkg=]PATH          ProGuard/R8 mapping.txt for Java/Kotlin
                                      deobfuscation (may be repeated).
                                      pkg= prefix scopes the map to a package.
   --no-auto-proguard-maps            Disable automatic ProGuard/R8 mapping
                                      discovery (e.g. Gradle project layout)
   --verbose                          Print more detailed output

 binary                               Converts text proto to binary format
   (no additional options)

NOTES:
 - If no input file is specified, reads from stdin
 - If no output file is specified, writes to stdout
 - Input/output files can be '-' to explicitly use stdin/stdout
)",
          argv0);
  return 1;
}

uint64_t StringToUint64OrDie(const char* str) {
  char* end;
  uint64_t number = static_cast<uint64_t>(strtoll(str, &end, 10));
  if (*end != '\0') {
    PERFETTO_ELOG("Invalid %s. Expected decimal integer.", str);
    exit(1);
  }
  return number;
}

int TextToTrace(std::istream* input, std::ostream* output) {
  std::string trace_text(std::istreambuf_iterator<char>{*input},
                         std::istreambuf_iterator<char>{});
  std::vector<uint8_t> descriptors;
  descriptors.reserve(kTraceDescriptor.size() +
                      kAndroidExtensionDescriptor.size());
  descriptors.insert(descriptors.end(), kTraceDescriptor.begin(),
                     kTraceDescriptor.end());
  descriptors.insert(descriptors.end(), kAndroidExtensionDescriptor.begin(),
                     kAndroidExtensionDescriptor.end());
  auto proto_status =
      protozero::TextToProto(descriptors.data(), descriptors.size(),
                             ".perfetto.protos.Trace", "trace", trace_text);
  if (!proto_status.ok()) {
    PERFETTO_ELOG("Failed to parse trace: %s",
                  proto_status.status().c_message());
    return 1;
  }
  const std::vector<uint8_t>& trace_proto = proto_status.value();
  output->write(reinterpret_cast<const char*>(trace_proto.data()),
                static_cast<int64_t>(trace_proto.size()));
  return 0;
}

int Main(int argc, char** argv) {
  std::vector<const char*> positional_args;
  trace_to_text::Keep truncate_keep = trace_to_text::Keep::kAll;
  uint64_t pid = 0;
  std::vector<uint64_t> timestamps;
  bool full_sort = false;
  std::optional<trace_to_text::ConversionMode> profile_type;
  bool profile_no_annotations = false;
  std::vector<std::string> symbol_paths;
  std::vector<trace_to_text::ProguardMapSpec> proguard_maps;
  bool no_auto_symbol_paths = false;
  bool no_auto_proguard_maps = false;
  bool verbose = false;
  bool skip_unknown_fields = false;
  std::string output_dir;
  for (int i = 1; i < argc; i++) {
    if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
      printf("%s\n", base::GetVersionString());
      return 0;
    }
    if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--truncate") == 0) {
      i++;
      if (i <= argc && strcmp(argv[i], "start") == 0) {
        truncate_keep = trace_to_text::Keep::kStart;
      } else if (i <= argc && strcmp(argv[i], "end") == 0) {
        truncate_keep = trace_to_text::Keep::kEnd;
      } else {
        PERFETTO_ELOG(
            "--truncate must specify whether to keep the end or the "
            "start of the trace.");
        return Usage(argv[0]);
      }
    } else if (i <= argc && strcmp(argv[i], "--pid") == 0) {
      i++;
      pid = StringToUint64OrDie(argv[i]);
    } else if (i <= argc && strcmp(argv[i], "--timestamps") == 0) {
      i++;
      std::vector<std::string> ts_strings = base::SplitString(argv[i], ",");
      for (const std::string& ts : ts_strings) {
        timestamps.emplace_back(StringToUint64OrDie(ts.c_str()));
      }
    } else if (strcmp(argv[i], "--alloc") == 0) {
      profile_type = trace_to_text::ConversionMode::kHeapProfile;
    } else if (strcmp(argv[i], "--perf") == 0) {
      profile_type = trace_to_text::ConversionMode::kPerfProfile;
    } else if (strcmp(argv[i], "--java-heap") == 0) {
      profile_type = trace_to_text::ConversionMode::kJavaHeapProfile;
    } else if (strcmp(argv[i], "--no-annotations") == 0) {
      profile_no_annotations = true;
    } else if (strcmp(argv[i], "--full-sort") == 0) {
      full_sort = true;
    } else if (i < argc && strcmp(argv[i], "--symbol-paths") == 0) {
      i++;
      symbol_paths = base::SplitString(argv[i], ",");
    } else if (strcmp(argv[i], "--no-auto-symbol-paths") == 0) {
      no_auto_symbol_paths = true;
    } else if (strcmp(argv[i], "--no-auto-proguard-maps") == 0) {
      no_auto_proguard_maps = true;
    } else if (i < argc && strcmp(argv[i], "--proguard-map") == 0) {
      i++;
      if (i >= argc) {
        PERFETTO_ELOG("--proguard-map requires an argument.");
        return Usage(argv[0]);
      }
      std::string arg = argv[i];
      size_t eq = arg.find('=');
      trace_to_text::ProguardMapSpec spec;
      if (eq == std::string::npos) {
        spec.path = std::move(arg);
      } else {
        spec.package = arg.substr(0, eq);
        spec.path = arg.substr(eq + 1);
      }
      proguard_maps.push_back(std::move(spec));
    } else if (strcmp(argv[i], "--verbose") == 0) {
      verbose = true;
    } else if (i < argc && strcmp(argv[i], "--output-dir") == 0) {
      i++;
      if (i >= argc) {
        PERFETTO_ELOG("--output-dir requires an argument.");
        return Usage(argv[0]);
      }
      output_dir = argv[i];
    } else if (strcmp(argv[i], "--skip-unknown") == 0) {
      skip_unknown_fields = true;
    } else {
      positional_args.push_back(argv[i]);
    }
  }

  if (positional_args.empty())
    return Usage(argv[0]);

  std::istream* input_stream;
  std::ifstream file_istream;
  if (positional_args.size() > 1) {
    const char* file_path = positional_args[1];
    file_istream.open(file_path, std::ios_base::in | std::ios_base::binary);
    if (!file_istream.is_open())
      PERFETTO_FATAL("Could not open %s", file_path);
    input_stream = &file_istream;
  } else {
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    if (isatty(STDIN_FILENO)) {
      PERFETTO_ELOG("Reading from stdin but it's connected to a TTY");
      PERFETTO_LOG("It is unlikely that you want to type in some binary.");
      PERFETTO_LOG("Either pass a file path to the cmdline or pipe stdin");
      return Usage(argv[0]);
    }
#endif
    input_stream = &std::cin;
  }

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // We don't want the runtime to replace "\n" with "\r\n" on `std::cout`.
  _setmode(_fileno(stdout), _O_BINARY);
#endif

  std::ostream* output_stream;
  std::ofstream file_ostream;
  if (positional_args.size() > 2) {
    const char* file_path = positional_args[2];
    file_ostream.open(file_path, std::ios_base::out | std::ios_base::trunc |
                                     std::ios_base::binary);
    if (!file_ostream.is_open())
      PERFETTO_FATAL("Could not open %s", file_path);
    output_stream = &file_ostream;
  } else {
    output_stream = &std::cout;
  }

  std::string format(positional_args[0]);

  if ((format != "profile" && format != "java_heap_profile") &&
      (pid != 0 || !timestamps.empty())) {
    PERFETTO_ELOG(
        "--pid and --timestamps are supported only for profile "
        "and java_heap_profile formats.");
    return 1;
  }

  if ((format != "profile" && format != "java_heap_profile") &&
      !output_dir.empty()) {
    PERFETTO_ELOG(
        "--output-dir is supported only for profile and java_heap_profile "
        "formats.");
    return 1;
  }

  if (format == "binary") {
    return TextToTrace(input_stream, output_stream);
  }

  if (format == "json")
    return trace_to_text::TraceToJson(input_stream, output_stream,
                                      /*compress=*/false, truncate_keep,
                                      full_sort);

  if (format == "systrace")
    return trace_to_text::TraceToSystrace(input_stream, output_stream,
                                          /*ctrace=*/false, truncate_keep,
                                          full_sort);

  if (format == "ctrace")
    return trace_to_text::TraceToSystrace(input_stream, output_stream,
                                          /*ctrace=*/true, truncate_keep,
                                          full_sort);

  if (truncate_keep != trace_to_text::Keep::kAll) {
    PERFETTO_ELOG(
        "--truncate is unsupported for "
        "text|profile|symbolize|decompress_packets format.");
    return 1;
  }

  if (full_sort) {
    PERFETTO_ELOG(
        "--full-sort is unsupported for "
        "text|profile|symbolize|decompress_packets format.");
    return 1;
  }

  if (format == "text") {
    trace_to_text::TraceToTextOptions options;
    options.skip_unknown_fields = skip_unknown_fields;
    return trace_to_text::TraceToText(input_stream, output_stream, options) ? 0
                                                                            : 1;
  }

  if (format == "profile") {
    if (positional_args.size() > 2) {
      PERFETTO_ELOG(
          "output file is not supported for \"profile\", use --output-dir "
          "instead");
      return Usage(argv[0]);
    }
    return trace_to_text::TraceToProfile(input_stream, pid, timestamps,
                                         !profile_no_annotations, output_dir,
                                         profile_type, verbose);
  }

  if (format == "java_heap_profile") {
    // legacy alias for "profile --java-heap"
    return trace_to_text::TraceToProfile(
        input_stream, pid, timestamps, !profile_no_annotations, output_dir,
        trace_to_text::ConversionMode::kJavaHeapProfile, verbose);
  }

  if (format == "symbolize")
    return trace_to_text::SymbolizeProfile(input_stream, output_stream,
                                           verbose);

  if (format == "deobfuscate")
    return trace_to_text::DeobfuscateProfile(input_stream, output_stream);

  if (format == "firefox")
    return trace_to_text::TraceToFirefoxProfile(input_stream, output_stream);

  if (format == "decompress_packets")
    return trace_to_text::UnpackCompressedPackets(input_stream, output_stream);

  if (format == "bundle") {
    // Bundle mode requires both input and output file paths
    if (positional_args.size() < 3) {
      PERFETTO_ELOG("Bundle mode requires both input and output file paths");
      return Usage(argv[0]);
    }

    const char* input_file = positional_args[1];
    const char* output_file = positional_args[2];

    // Validate that stdin/stdout are not used for bundle mode
    if (strcmp(input_file, "-") == 0) {
      PERFETTO_ELOG(
          "Bundle mode does not support stdin input, provide file path");
      return 1;
    }
    if (strcmp(output_file, "-") == 0) {
      PERFETTO_ELOG(
          "Bundle mode does not support stdout output, provide file path");
      return 1;
    }

    // Validate input file exists and is readable
    if (!base::FileExists(input_file)) {
      PERFETTO_ELOG("Input file does not exist: %s", input_file);
      return 1;
    }

    trace_to_text::BundleContext context;
    context.symbol_paths = symbol_paths;
    context.proguard_maps = std::move(proguard_maps);
    context.no_auto_symbol_paths = no_auto_symbol_paths;
    context.no_auto_proguard_maps = no_auto_proguard_maps;
    context.verbose = verbose;
    if (const char* val = getenv("ANDROID_PRODUCT_OUT")) {
      context.android_product_out = val;
    }
    if (const char* val = getenv("HOME")) {
      context.home_dir = val;
    }
    context.root_dir = "/";
    return trace_to_text::TraceToBundle(input_file, output_file, context);
  }

  return Usage(argv[0]);
}

}  // namespace

int TraceconvMain(int argc, char** argv) {
  return Main(argc, argv);
}

}  // namespace perfetto::traceconv
