// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/342213636): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include "content/browser/child_process_launcher_helper.h"

#import <BrowserEngineKit/BrowserEngineKit.h>

#include <list>

#include "base/apple/mach_port_rendezvous_ios.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/child_process_launcher_helper_posix.h"
#include "content/public/browser/child_process_launcher_utils.h"
#include "content/public/common/content_switches.h"
#include "gpu/ipc/common/surface_handle.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "ui/accelerated_widget_mac/ca_layer_frame_sink_provider.h"

namespace content {
namespace internal {

static base::NoDestructor<base::Lock> g_process_table_lock_;
static base::NoDestructor<
    std::map<pid_t, scoped_refptr<ChildProcessLauncherHelper>>>
    g_process_table_;

void InvalidateProcess(NSObject* process) {
  if ([process isKindOfClass:[BEWebContentProcess class]]) {
    [(BEWebContentProcess*)process invalidate];
  } else if ([process isKindOfClass:[BENetworkingProcess class]]) {
    [(BENetworkingProcess*)process invalidate];
  } else if ([process isKindOfClass:[BERenderingProcess class]]) {
    [(BERenderingProcess*)process invalidate];
  }
}

void OnChildProcessTerminatedOnAnyThread(pid_t process_id) {
  base::AutoLock guard(*g_process_table_lock_);
  auto it = g_process_table_->find(process_id);
  if (it != g_process_table_->end()) {
    it->second->ClearProcessStorage();
    g_process_table_->erase(it);
  }
}

bool WaitForExit(pid_t process_id, int* exit_code, base::TimeDelta timeout) {
  base::TimeTicks wakeup_time = base::TimeTicks::Now() + timeout;
  constexpr uint32_t kMaxSleepInMicroseconds = 1 << 18;  // ~256 ms.
  uint32_t max_sleep_time_usecs = 1 << 10;               // ~1 ms.
  int double_sleep_time = 0;

  while (true) {
    {
      base::AutoLock guard(*g_process_table_lock_);
      auto it = g_process_table_->find(process_id);
      if (it != g_process_table_->end()) {
        if (it->second->GetProcess() == nullptr) {
          if (exit_code) {
            *exit_code = it->second->GetExitCode().value_or(0);
          }
          return true;
        }
      } else {
        return true;
      }
    }
    base::TimeTicks now = base::TimeTicks::Now();
    if (now > wakeup_time) {
      return false;
    }

    const uint32_t sleep_time_usecs = static_cast<uint32_t>(
        std::min(static_cast<uint64_t>((wakeup_time - now).InMicroseconds()),
                 uint64_t{max_sleep_time_usecs}));
    base::PlatformThread::Sleep(base::Microseconds(sleep_time_usecs));
    if ((max_sleep_time_usecs < kMaxSleepInMicroseconds) &&
        (double_sleep_time++ % 4 == 0)) {
      max_sleep_time_usecs *= 2;
    }
  }
}

bool TerminateNow(pid_t process_id, int exit_code, bool wait) {
  NSObject* process = nullptr;
  {
    base::AutoLock guard(*g_process_table_lock_);
    auto it = g_process_table_->find(process_id);
    if (it != g_process_table_->end()) {
      it->second->SetExitCode(exit_code);
      process = it->second->GetProcess();
    }
  }

  if (!process) {
    return false;
  }
  InvalidateProcess(process);
  if (wait) {
    return WaitForExit(process_id, nullptr, base::Seconds(60));
  }
  return true;
}

// Object used to pass the result of the launch from the async
// dispatch_queue to the LauncherThread.
class LaunchResult {
 public:
  void Invalidate() { InvalidateProcess(process); }

  id<BEProcessCapabilityGrant> GrantForeground(NSError** error) {
    id<BEProcessCapabilityGrant> grant;
    BEProcessCapability* cap = [BEProcessCapability foreground];
    if ([process isKindOfClass:[BEWebContentProcess class]]) {
      grant = [(BEWebContentProcess*)process grantCapability:cap error:error];
    } else if ([process isKindOfClass:[BENetworkingProcess class]]) {
      grant = [(BENetworkingProcess*)process grantCapability:cap error:error];
    } else if ([process isKindOfClass:[BERenderingProcess class]]) {
      grant = [(BERenderingProcess*)process grantCapability:cap error:error];
    }
    return grant;
  }

  xpc_connection_t CreateXPCConnection(NSError** error) {
    if ([process isKindOfClass:[BEWebContentProcess class]]) {
      return [(BEWebContentProcess*)process makeLibXPCConnectionError:error];
    } else if ([process isKindOfClass:[BENetworkingProcess class]]) {
      return [(BENetworkingProcess*)process makeLibXPCConnectionError:error];
    } else if ([process isKindOfClass:[BERenderingProcess class]]) {
      return [(BERenderingProcess*)process makeLibXPCConnectionError:error];
    }
    return {};
  }

  NSObject* process;
  NSError* launch_error;
};

// Object to store the process handles.
class ProcessStorage : public ProcessStorageBase {
 public:
  ProcessStorage(NSObject* process,
                 xpc_connection_t connection,
                 id<BEProcessCapabilityGrant> grant)
      : process_(process), ipc_channel_(connection), grant_(grant) {}

  ~ProcessStorage() override { [grant_ invalidate]; }

  void ReleaseProcess() override { process_ = nullptr; }

  NSObject* Process() { return process_; }

 private:
  NSObject* process_;
  [[maybe_unused]] xpc_connection_t ipc_channel_;
  id<BEProcessCapabilityGrant> grant_;
};

std::optional<mojo::NamedPlatformChannel>
ChildProcessLauncherHelper::CreateNamedPlatformChannelOnLauncherThread() {
  DCHECK(CurrentlyOnProcessLauncherTaskRunner());
  return std::nullopt;
}

void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
  DCHECK(client_task_runner_->RunsTasksInCurrentSequence());
}

std::unique_ptr<PosixFileDescriptorInfo>
ChildProcessLauncherHelper::GetFilesToMap() {
  DCHECK(CurrentlyOnProcessLauncherTaskRunner());
  return CreateDefaultPosixFilesToMap(
      child_process_id(), mojo_channel_->remote_endpoint(),
      /*files_to_preload=*/{}, GetProcessType(), command_line());
}

bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
    FileMappedForLaunch& files_to_register,
    base::LaunchOptions* options) {
  mojo::PlatformHandle endpoint =
      mojo_channel_->TakeRemoteEndpoint().TakePlatformHandle();
  DCHECK(endpoint.is_valid_mach_receive());
  options->mach_ports_for_rendezvous.insert(std::make_pair(
      'mojo', base::MachRendezvousPort(endpoint.TakeMachReceiveRight())));
  return true;
}

ChildProcessLauncherHelper::Process
ChildProcessLauncherHelper::LaunchProcessOnLauncherThread(
    const base::LaunchOptions* options,
    std::unique_ptr<PosixFileDescriptorInfo> files_to_register,
    bool* is_synchronous_launch,
    int* launch_result) {
  DCHECK(options);
  *is_synchronous_launch = false;
  rendezvous_server_ = std::make_unique<base::MachPortRendezvousServerIOS>(
      options->mach_ports_for_rendezvous);

  // We need to hand out unique "process ids" just use a static counter
  // for now. There should only be one launcher thread so this is
  // synchronous access it doesn't need to be an atomic.
  static pid_t g_pid = 0;
  pid_t process_id = ++g_pid;

  static bool g_hooks_registered = false;
  if (!g_hooks_registered) {
    base::Process::SetTerminationHooks(&TerminateNow, &WaitForExit);
    g_hooks_registered = true;
  }

  void (^process_terminated)() = ^void() {
    OnChildProcessTerminatedOnAnyThread(process_id);
  };
  std::string process_type = GetProcessType();
  std::string utility_sub_type =
      command_line()->GetSwitchValueASCII(switches::kUtilitySubType);
  if (process_type == switches::kUtilityProcess) {
    void (^process_launch_complete)(BENetworkingProcess* process,
                                    NSError* error) =
        ^void(BENetworkingProcess* process, NSError* error) {
          auto result = std::make_unique<LaunchResult>(process, error);
          GetProcessLauncherTaskRunner()->PostTask(
              FROM_HERE,
              base::BindOnce(&ChildProcessLauncherHelper::OnChildProcessStarted,
                             this, process_id, std::move(result)));
        };

    [BENetworkingProcess
        networkProcessWithInterruptionHandler:process_terminated
                                   completion:process_launch_complete];

  } else if (process_type == switches::kGpuProcess) {
    void (^process_launch_complete)(BERenderingProcess* process,
                                    NSError* error) =
        ^void(BERenderingProcess* process, NSError* error) {
          auto result = std::make_unique<LaunchResult>(process, error);
          GetProcessLauncherTaskRunner()->PostTask(
              FROM_HERE,
              base::BindOnce(&ChildProcessLauncherHelper::OnChildProcessStarted,
                             this, process_id, std::move(result)));
        };

    [BERenderingProcess
        renderingProcessWithInterruptionHandler:process_terminated
                                     completion:process_launch_complete];
  } else {
    // This can be both kUtility and kRenderProcess.
    void (^process_launch_complete)(BEWebContentProcess* process,
                                    NSError* error) =
        ^void(BEWebContentProcess* process, NSError* error) {
          auto result = std::make_unique<LaunchResult>(process, error);
          GetProcessLauncherTaskRunner()->PostTask(
              FROM_HERE,
              base::BindOnce(&ChildProcessLauncherHelper::OnChildProcessStarted,
                             this, process_id, std::move(result)));
        };

    [BEWebContentProcess
        webContentProcessWithInterruptionHandler:process_terminated
                                      completion:process_launch_complete];
  }
  AddRef();
  return Process();
}

void ChildProcessLauncherHelper::OnChildProcessStarted(
    pid_t process_id,
    std::unique_ptr<LaunchResult> launch_result) {
  DCHECK(CurrentlyOnProcessLauncherTaskRunner());
  scoped_refptr<ChildProcessLauncherHelper> ref(this);
  Release();  // Balances with LaunchProcessOnLauncherThread.

  int launch_result_code = LAUNCH_RESULT_FAILURE;

  if (!launch_result->launch_error) {
    NSError* error = nil;

    // TODO(dtapuska): For now we grant everything foreground capability. We
    // need to hook this grant up to the
    // `RenderProcessHostImpl::UpdateProcessPriority()`.
    id<BEProcessCapabilityGrant> grant = launch_result->GrantForeground(&error);

    xpc_connection_t xpc_connection =
        launch_result->CreateXPCConnection(&error);
    if (xpc_connection) {
      scoped_refptr<base::SequencedTaskRunner> client_task_runner =
          client_task_runner_;
      bool is_gpu_process = GetProcessType() == switches::kGpuProcess;

      xpc_connection_set_event_handler(xpc_connection, ^(xpc_object_t event) {
        if (event == XPC_ERROR_CONNECTION_INTERRUPTED ||
            event == XPC_ERROR_CONNECTION_INVALID) {
          OnChildProcessTerminatedOnAnyThread(process_id);
          return;
        }

        const char* message_type = xpc_dictionary_get_string(event, "message");
        if (message_type && strcmp(message_type, "layerHandle") == 0) {
          // We only expect this message from the GPU process.
          if (!is_gpu_process) {
            xpc_connection_cancel(xpc_connection);
            return;
          }
          xpc_object_t ca_layer_handle =
              xpc_dictionary_get_value(event, "layer");
          gpu::SurfaceHandle view_handle =
              xpc_dictionary_get_uint64(event, "handle");

          // Validate arguments.
          if (!ca_layer_handle || !view_handle) {
            xpc_connection_cancel(xpc_connection);
            return;
          }

          client_task_runner->PostTask(
              FROM_HERE,
              base::BindOnce(
                  [](gpu::SurfaceHandle view_handle,
                     xpc_object_t ca_layer_handle) {
                    NSError* error = nullptr;
                    BELayerHierarchyHandle* be_handle = [BELayerHierarchyHandle
                        handleWithXPCRepresentation:ca_layer_handle
                                              error:&error];
                    CALayerFrameSinkProvider* sink =
                        [CALayerFrameSinkProvider lookupByHandle:view_handle];
                    if (sink) {
                      sink.handle = be_handle;
                    }
                  },
                  view_handle, ca_layer_handle));
        }
      });
      xpc_connection_resume(xpc_connection);
      xpc_object_t message = xpc_dictionary_create(nil, nil, 0);
      xpc_object_t args_array = xpc_array_create_empty();
      for (const auto& arg : command_line()->argv()) {
        xpc_object_t value = xpc_string_create(arg.c_str());
        xpc_array_append_value(args_array, value);
      }
      xpc_dictionary_set_value(message, "args", args_array);
      xpc_dictionary_set_fd(message, "stdout", STDOUT_FILENO);
      xpc_dictionary_set_fd(message, "stderr", STDERR_FILENO);

      // We create a scoped temporary directory for the child process.
      // In order to share this unique directory with the child process
      // we need to create bookmark data and then pass this over XPC
      // to the child process. The child process will then deserialize
      // it before then assigning the TMPDIR environment variable. We
      // do this via XPC so that it is done early enough in the process
      // creation so TMPDIR is set before any real Chromium code runs.
      scoped_temp_dir_ = std::make_unique<base::ScopedTempDir>();
      CHECK(scoped_temp_dir_->CreateUniqueTempDir());

      NSURL* temp_dir_url = [[NSURL alloc]
          initFileURLWithPath:base::SysUTF8ToNSString(
                                  scoped_temp_dir_->GetPath().value())];
      NSData* bookmark_temp_dir = [temp_dir_url
                 bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
          includingResourceValuesForKeys:nil
                           relativeToURL:nil
                                   error:&error];
      CHECK(error == nil) << base::SysNSStringToUTF8(
          [error localizedDescription]);

      xpc_dictionary_set_data(message, "tmp_dir", bookmark_temp_dir.bytes,
                              bookmark_temp_dir.length);

      if (is_gpu_process) {
        // This should match the bundle ID that we set for the GPU process which
        // for content_shell is in //content/shell/app/BUILD.gn and for chrome
        // is in //ios/chrome/app/chrome_app.gni. In both cases we append the
        // ".GPUProcessExtension" suffix to the main bundle ID.
        NSString* gpu_bundle_id = [[[NSBundle mainBundle] bundleIdentifier]
            stringByAppendingString:@".GPUProcessExtension"];

        // Create a cache directory for the GPU extension process.
        base::FilePath gpu_cache_path =
            base::PathService::CheckedGet(base::DIR_CACHE)
                .AppendUTF8(base::SysNSStringToUTF8(gpu_bundle_id));

        base::File::Error file_error = base::File::FILE_OK;
        CHECK(base::CreateDirectoryAndGetError(gpu_cache_path, &file_error))
            << base::File::ErrorToString(file_error);

        NSURL* gpu_cache_url = [NSURL
            fileURLWithPath:base::SysUTF8ToNSString(gpu_cache_path.value())
                isDirectory:TRUE];

        // Put the cache directory in a bookmark, similar to TMP_DIR.
        NSData* gpu_cache_bookmark = [gpu_cache_url
                   bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
            includingResourceValuesForKeys:nil
                             relativeToURL:nil
                                     error:&error];
        CHECK(error == nil)
            << base::SysNSStringToUTF8([error localizedDescription]);

        xpc_dictionary_set_data(message, "gpu_cache_dir",
                                gpu_cache_bookmark.bytes,
                                gpu_cache_bookmark.length);

        // Per Apple, this needs to be propagated to the extension process to
        // setenv the same value there.
        const char* container_home_path = getenv("CFFIXED_USER_HOME");
        CHECK_NE(container_home_path, nullptr);
        xpc_dictionary_set_string(message, "browser_container_home",
                                  container_home_path);
      }

      xpc_dictionary_set_mach_send(
          message, "port", rendezvous_server_->GetMachSendRight().get());
      xpc_connection_send_message(xpc_connection, message);
      launch_result_code = LAUNCH_RESULT_SUCCESS;

      // Keep reference to process, xpc_connection and the grant for the process
      // life.
      process_storage_ = std::make_unique<ProcessStorage>(
          launch_result->process, xpc_connection, grant);

      // Add the process to the global table.
      {
        base::AutoLock guard(*g_process_table_lock_);
        CHECK(!base::Contains(*g_process_table_, process_id));
        g_process_table_->emplace(process_id, this);
      }

    } else {
      [grant invalidate];
      launch_result->Invalidate();
    }
  }

  ChildProcessLauncherHelper::Process process;
  process.process = base::Process(process_id);
#if TARGET_OS_SIMULATOR
  process.process.SetIsContentProcess();
#endif
  PostLaunchOnLauncherThread(std::move(process), launch_result_code);
}

bool ChildProcessLauncherHelper::IsUsingLaunchOptions() {
  return true;
}

void ChildProcessLauncherHelper::AfterLaunchOnLauncherThread(
    const ChildProcessLauncherHelper::Process& process,
    const base::LaunchOptions* options) {}

ChildProcessTerminationInfo ChildProcessLauncherHelper::GetTerminationInfo(
    const ChildProcessLauncherHelper::Process& process,
    bool known_dead) {
  ChildProcessTerminationInfo info;
  if (!process_storage_) {
    info.status = base::TERMINATION_STATUS_LAUNCH_FAILED;
  } else if (static_cast<ProcessStorage*>(process_storage_.get())->Process() ==
             nullptr) {
    if (exit_code_.has_value()) {
      if (exit_code_.value() == RESULT_CODE_NORMAL_EXIT) {
        info.status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
      } else {
        info.status = base::TERMINATION_STATUS_PROCESS_WAS_KILLED;
      }
    } else {
      info.status = base::TERMINATION_STATUS_PROCESS_CRASHED;
    }
  } else {
    info.status = base::TERMINATION_STATUS_STILL_RUNNING;
  }
  return info;
}

void ChildProcessLauncherHelper::ClearProcessStorage() {
  if (process_storage_) {
    process_storage_->ReleaseProcess();
  }
}

void ChildProcessLauncherHelper::SetExitCode(int exit_code) {
  exit_code_ = exit_code;
}

std::optional<int> ChildProcessLauncherHelper::GetExitCode() {
  return exit_code_;
}

NSObject* ChildProcessLauncherHelper::GetProcess() {
  if (process_storage_) {
    return static_cast<ProcessStorage*>(process_storage_.get())->Process();
  }
  return nullptr;
}

// static
bool ChildProcessLauncherHelper::TerminateProcess(const base::Process& process,
                                                  int exit_code) {
  // TODO(crbug.com/40565504): Determine whether we should also call
  // EnsureProcessTerminated() to make sure of process-exit, and reap it.
  return process.Terminate(exit_code, false);
}

// static
void ChildProcessLauncherHelper::ForceNormalProcessTerminationSync(
    ChildProcessLauncherHelper::Process process) {
  DCHECK(CurrentlyOnProcessLauncherTaskRunner());
  // Client has gone away, so just kill the process.  Using exit code 0 means
  // that UMA won't treat this as a crash.
  process.process.Terminate(RESULT_CODE_NORMAL_EXIT, false);
  base::EnsureProcessTerminated(std::move(process.process));
}

void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread(
    base::Process process,
    base::Process::Priority priority) {}

// static
base::File OpenFileToShare(const base::FilePath& path,
                           base::MemoryMappedFile::Region* region) {
  // Not used yet (until required files are described in the service manifest on
  // iOS).
  NOTREACHED();
}

}  //  namespace internal
}  // namespace content
