// Copyright 2016 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 "lib/component/cpp/startup_context.h"

#include <lib/async/default.h>
#include <lib/fdio/util.h>
#include <zircon/process.h>
#include <zircon/processargs.h>

#include "lib/component/cpp/connect.h"
#include "lib/fxl/logging.h"

namespace component {

namespace {

constexpr char kServiceRootPath[] = "/svc";

}  // namespace

StartupContext::StartupContext(zx::channel service_root,
                               zx::channel directory_request)
    : incoming_services_(std::make_shared<Services>()) {
  incoming_services_->Bind(std::move(service_root));
  outgoing_.Serve(std::move(directory_request));
}

StartupContext::~StartupContext() = default;

// static
std::unique_ptr<StartupContext> StartupContext::CreateFromStartupInfo() {
  zx_handle_t directory_request = zx_take_startup_handle(PA_DIRECTORY_REQUEST);
  return std::make_unique<StartupContext>(
      subtle::CreateStaticServiceRootHandle(), zx::channel(directory_request));
}

// static
std::unique_ptr<StartupContext>
StartupContext::CreateFromStartupInfoNotChecked() {
  return CreateFromStartupInfo();
}

std::unique_ptr<StartupContext> StartupContext::CreateFrom(
    fuchsia::sys::StartupInfo startup_info) {
  fuchsia::sys::FlatNamespace& flat = startup_info.flat_namespace;
  if (flat.paths.size() != flat.directories.size())
    return nullptr;

  zx::channel service_root;
  for (size_t i = 0; i < flat.paths.size(); ++i) {
    if (flat.paths.at(i) == kServiceRootPath) {
      service_root = std::move(flat.directories.at(i));
      break;
    }
  }

  return std::make_unique<StartupContext>(
      std::move(service_root),
      std::move(startup_info.launch_info.directory_request));
}

const fuchsia::sys::EnvironmentPtr& StartupContext::environment() const {
  std::lock_guard<std::mutex> guard(services_mutex_);
  if (!environment_) {
    incoming_services_->ConnectToService(environment_.NewRequest());
  }
  return environment_;
}

const fuchsia::sys::LauncherPtr& StartupContext::launcher() const {
  std::lock_guard<std::mutex> guard(services_mutex_);
  if (!launcher_) {
    incoming_services_->ConnectToService(launcher_.NewRequest());
  }
  return launcher_;
}

void StartupContext::ConnectToEnvironmentService(
    const std::string& interface_name, zx::channel channel) {
  incoming_services()->ConnectToService(std::move(channel), interface_name);
}

namespace subtle {

// static
zx::channel CreateStaticServiceRootHandle() {
  zx::channel h1, h2;
  if (zx::channel::create(0, &h1, &h2) != ZX_OK)
    return zx::channel();
  // TODO(abarth): Use kServiceRootPath once that actually works.
  if (fdio_service_connect("/svc/.", h1.release()) != ZX_OK)
    return zx::channel();
  return h2;
}

}  // namespace subtle

}  // namespace component
