// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// It is __imperative__ that the functions in this file are __not__ included in
// release or profile builds.
//
// They call into the "private" ptrace() API to ensure that the current process
// is being ptrace()-d. Only debug builds rely on ptrace(), and the ptrace() API
// is not allowed for use in the App Store, so we must exclude it from profile-
// and release-builds.
//
// When an app is launched from a host workstation (e.g. via Xcode or
// "ios-deploy"), the process is already ptrace()-d by debugserver. However,
// when an app is launched from the home screen, it is not, so for debug builds
// we initialize the ptrace() relationship via PT_TRACE_ME if necessary.
//
// Please see the following documents for more details:
//   - go/decommissioning-dbc
//   - go/decommissioning-dbc-engine
//   - go/decommissioning-dbc-tools

#include "flutter/runtime/ptrace_check.h"

#if TRACING_CHECKS_NECESSARY

#include <sys/sysctl.h>
#include <sys/types.h>

#include <mutex>

#include "flutter/fml/build_config.h"

// Being extra careful and adding additional landmines that will prevent
// compilation of this TU in an incorrect runtime mode.
static_assert(OS_IOS, "This translation unit is iOS specific.");
static_assert(FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG,
              "This translation unit must only be compiled in the debug "
              "runtime mode as it "
              "contains private API usage.");

#define PT_TRACE_ME 0
#define PT_SIGEXC 12
extern "C" int ptrace(int request, pid_t pid, caddr_t addr, int data);

namespace flutter {

static bool IsLaunchedByFlutterCLI(const Settings& vm_settings) {
  // Only the Flutter CLI passes "--enable-checked-mode". Therefore, if the flag
  // is present, we have been launched by "ios-deploy" via "debugserver".
  //
  // We choose this flag because it is always passed to launch debug builds.
  return vm_settings.enable_checked_mode;
}

static bool IsLaunchedByXcode() {
  // Use "sysctl()" to check if we're currently being debugged (e.g. by Xcode).
  // We could also check "getppid() != 1" (launchd), but this is more direct.
  const pid_t self = getpid();
  int mib[5] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, self, 0};

  auto proc = std::make_unique<struct kinfo_proc>();
  size_t proc_size = sizeof(struct kinfo_proc);
  if (::sysctl(mib, 4, proc.get(), &proc_size, nullptr, 0) < 0) {
    FML_LOG(ERROR) << "Could not execute sysctl() to get current process info: "
                   << strerror(errno);
    return false;
  }

  return proc->kp_proc.p_flag & P_TRACED;
}

static bool EnableTracingManually(const Settings& vm_settings) {
  if (::ptrace(PT_TRACE_ME, 0, nullptr, 0) == -1) {
    FML_LOG(ERROR) << "Could not call ptrace(PT_TRACE_ME): " << strerror(errno);
    // No use trying PT_SIGEXC -- it's only needed if PT_TRACE_ME succeeds.
    return false;
  }

  if (::ptrace(PT_SIGEXC, 0, nullptr, 0) == -1) {
    FML_LOG(ERROR) << "Could not call ptrace(PT_SIGEXC): " << strerror(errno);
    return false;
  }

  // The previous operation causes this process to not be reaped after it
  // terminates (even if PT_SIGEXC fails). Issue a warning to the console every
  // (approximiately) maxproc/10 leaks. See the links above for an explanation
  // of this issue.
  size_t maxproc = 0;
  size_t maxproc_size = sizeof(size_t);
  const int sysctl_result =
      ::sysctlbyname("kern.maxproc", &maxproc, &maxproc_size, nullptr, 0);
  if (sysctl_result < 0) {
    FML_LOG(ERROR)
        << "Could not execute sysctl() to determine process count limit: "
        << strerror(errno);
    return false;
  }

  const char* warning =
      "Launching a debug-mode app from the home screen may cause problems.\n"
      "Please compile a profile-/release-build, launch your app via \"flutter "
      "run\", or see https://github.com/flutter/flutter/wiki/"
      "PID-leak-in-iOS-debug-builds-launched-from-home-screen for details.";

  if (vm_settings.verbose_logging  // used for testing and also informative
      || sysctl_result < 0         // could not determine maximum process count
      || maxproc / 10 == 0         // avoid division (%) by 0
      || getpid() % (maxproc / 10) == 0)  // warning every ~maxproc/10 leaks
  {
    FML_LOG(ERROR) << warning;
  }

  return true;
}

static bool EnableTracingIfNecessaryOnce(const Settings& vm_settings) {
  if (IsLaunchedByFlutterCLI(vm_settings)) {
    return true;
  }

  if (IsLaunchedByXcode()) {
    return true;
  }

  return EnableTracingManually(vm_settings);
}

static TracingResult sTracingResult = TracingResult::kNotAttempted;

bool EnableTracingIfNecessaryImpl(const Settings& vm_settings) {
  static std::once_flag tracing_flag;

  std::call_once(tracing_flag, [&vm_settings]() {
    sTracingResult = EnableTracingIfNecessaryOnce(vm_settings)
                         ? TracingResult::kEnabled
                         : TracingResult::kDisabled;
  });
  return sTracingResult != TracingResult::kDisabled;
}

TracingResult GetTracingResultImpl() {
  return sTracingResult;
}

}  // namespace flutter

#endif  // TRACING_CHECKS_NECESSARY
