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

#include "src/developer/debug/debug_agent/zircon_binary_launcher.h"

#include <inttypes.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/io.h>
#include <zircon/processargs.h>

#include <utility>

#include "src/developer/debug/debug_agent/zircon_process_handle.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace debug_agent {

ZirconBinaryLauncher::ZirconBinaryLauncher(fidl::UnownedClientEnd<fuchsia_io::Directory> svc_dir)
    : builder_(svc_dir) {}
ZirconBinaryLauncher::~ZirconBinaryLauncher() = default;

debug::Status ZirconBinaryLauncher::Setup(const std::vector<std::string>& argv) {
  if (zx_status_t status = builder_.LoadPath(argv[0]); status != ZX_OK) {
    if (status == ZX_ERR_NOT_FOUND) {
      // Rewrite this common error to provide a better message.
      return debug::Status(debug::Status::kNotFound,
                           fxl::StringPrintf("The binary '%s' was not found.", argv[0].c_str()));
    }
    return debug::ZxStatus(status);
  }

  if (zx_status_t status = builder_.AddArgs(argv); status != ZX_OK) {
    return debug::ZxStatus(status);
  }
  if (zx_status_t status = builder_.CloneJob(); status != ZX_OK) {
    return debug::ZxStatus(status);
  }
  if (zx_status_t status = builder_.CloneNamespace(); status != ZX_OK) {
    return debug::ZxStatus(status);
  }
  if (zx_status_t status = builder_.CloneEnvironment(); status != ZX_OK) {
    return debug::ZxStatus(status);
  }

  stdio_handles_.out = AddStdioEndpoint(STDOUT_FILENO);
  stdio_handles_.err = AddStdioEndpoint(STDERR_FILENO);

  return debug::ZxStatus(builder_.Prepare(nullptr));
}

std::unique_ptr<ProcessHandle> ZirconBinaryLauncher::GetProcess() const {
  zx::process process;
  builder_.data().process().duplicate(ZX_RIGHT_SAME_RIGHTS, &process);
  return std::make_unique<ZirconProcessHandle>(std::move(process));
}

debug::Status ZirconBinaryLauncher::Start() { return debug::ZxStatus(builder_.Start(nullptr)); }

zx::socket ZirconBinaryLauncher::AddStdioEndpoint(int fd) {
  zx::socket local;
  zx::socket target;
  zx_status_t status = zx::socket::create(0, &local, &target);
  if (status != ZX_OK)
    return zx::socket();

  builder_.AddHandle(PA_HND(PA_FD, fd), std::move(target));
  return local;
}

StdioHandles ZirconBinaryLauncher::ReleaseStdioHandles() { return std::move(stdio_handles_); }

}  // namespace debug_agent
