// Copyright 2021 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 "runner.h"

#include <fuchsia/component/cpp/fidl.h>
#include <fuchsia/component/runner/cpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fpromise/result.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>
#include <zircon/status.h>

#include <memory>
#include <utility>

#include <src/lib/fsl/io/fd.h>
#include <src/lib/fsl/vmo/file.h>
#include <src/lib/fsl/vmo/sized_vmo.h>
#include <src/lib/pkg_url/fuchsia_pkg_url.h>
#include <src/sys/run_test_component/test_metadata.h>

#include "test_component.h"

namespace {
struct ComponentArgs {
  std::string legacy_url;
  std::shared_ptr<run::TestMetadata> test_metadata;
  std::shared_ptr<sys::ServiceDirectory> test_component_svc;
  fidl::InterfaceHandle<fuchsia::io::Directory> component_pkg;
  std::vector<fuchsia::component::runner::ComponentNamespaceEntry> ns;
};

fpromise::result<ComponentArgs, fuchsia::component::Error> GetComponentArgs(
    fuchsia::component::runner::ComponentStartInfo& start_info) {
  component::FuchsiaPkgUrl url;
  if (!url.Parse(start_info.resolved_url())) {
    FX_LOGS(WARNING) << "cannot run test: " << start_info.resolved_url()
                     << ", as we cannot parse url.";
    return fpromise::error(fuchsia::component::Error::INVALID_ARGUMENTS);
  }

  if (!start_info.program().has_entries()) {
    FX_LOGS(WARNING) << "cannot run test: " << start_info.resolved_url()
                     << ", as it has no program entry.";
    return fpromise::error(fuchsia::component::Error::INVALID_ARGUMENTS);
  }
  auto& program_entries = start_info.program().entries();
  auto it = std::find_if(
      program_entries.begin(), program_entries.end(),
      [](const fuchsia::data::DictionaryEntry& entry) { return entry.key == "legacy_manifest"; });
  if (it == program_entries.end()) {
    FX_LOGS(WARNING) << "cannot run test: " << start_info.resolved_url()
                     << ", as it has no legacy_manifest entry.";
    return fpromise::error(fuchsia::component::Error::INVALID_ARGUMENTS);
  }

  auto ns = std::move(*start_info.mutable_ns());
  const std::string& legacy_manifest = it->value->str();

  auto pkg_it = std::find_if(ns.begin(), ns.end(),
                             [](fuchsia::component::runner::ComponentNamespaceEntry& entry) {
                               return entry.path() == "/pkg";
                             });

  auto component_pkg = std::move(*pkg_it->mutable_directory());

  auto fd = fsl::OpenChannelAsFileDescriptor(component_pkg.TakeChannel());
  fsl::SizedVmo vmo;
  if (!fsl::VmoFromFilenameAt(fd.get(), legacy_manifest, &vmo)) {
    FX_LOGS(WARNING) << "cannot run test: " << start_info.resolved_url()
                     << ", as cannot read legacy manifest file.";
    return fpromise::error(fuchsia::component::Error::INSTANCE_CANNOT_START);
  }

  const uint64_t size = vmo.size();
  std::string cmx_str(size, ' ');
  auto status = vmo.vmo().read(cmx_str.data(), 0, size);
  if (status != ZX_OK) {
    FX_LOGS(WARNING) << "cannot run test: " << start_info.resolved_url()
                     << ", as cannot read legacy manifest file: " << zx_status_get_string(status)
                     << ".";
    return fpromise::error(fuchsia::component::Error::INSTANCE_CANNOT_START);
  }
  auto legacy_url = url.package_path() + "#" + legacy_manifest;
  auto test_metadata = std::make_shared<run::TestMetadata>();
  if (!test_metadata->ParseFromString(cmx_str, legacy_manifest)) {
    FX_LOGS(WARNING) << "cannot run test: " << start_info.resolved_url()
                     << ".\nError parsing cmx: " << legacy_manifest << ", "
                     << test_metadata->error_str();
    return fpromise::error(fuchsia::component::Error::INSTANCE_CANNOT_START);
  }

  auto svc_it = std::find_if(ns.begin(), ns.end(),
                             [](fuchsia::component::runner::ComponentNamespaceEntry& entry) {
                               return entry.path() == "/svc";
                             });

  auto component_svc =
      std::make_shared<sys::ServiceDirectory>(std::move(*svc_it->mutable_directory()));

  return fpromise::ok(ComponentArgs{.legacy_url = std::move(legacy_url),
                                    .test_metadata = std::move(test_metadata),
                                    .test_component_svc = std::move(component_svc),
                                    .component_pkg = std::move(component_pkg),
                                    .ns = std::move(ns)});
}

}  // namespace

Runner::Runner(std::shared_ptr<sys::ServiceDirectory> svc, async_dispatcher_t* dispatcher)
    : svc_(std::move(svc)), dispatcher_(dispatcher) {}

Runner::~Runner() = default;

void Runner::Start(
    fuchsia::component::runner::ComponentStartInfo start_info,
    fidl::InterfaceRequest<fuchsia::component::runner::ComponentController> controller) {
  auto args_result = GetComponentArgs(start_info);

  if (args_result.is_error()) {
    controller.Close(static_cast<zx_status_t>(args_result.take_error()));
    return;
  }

  auto args = args_result.take_value();
  FX_LOGS(INFO) << "running test: " << args.legacy_url;

  auto env_proxy = svc_->Connect<fuchsia::sys::Environment>();
  fidl::InterfaceHandle<fuchsia::io::Directory> dir;
  env_proxy->GetDirectory(dir.NewRequest().TakeChannel());
  auto env_svc = std::make_shared<sys::ServiceDirectory>(dir.TakeChannel());

  auto test_component = std::make_unique<TestComponent>(
      TestComponentArgs{.legacy_url = std::move(args.legacy_url),
                        .outgoing_dir = start_info.mutable_outgoing_dir()->TakeChannel(),
                        .parent_env = std::move(env_proxy),
                        .parent_env_svc = std::move(env_svc),
                        .test_component_svc = std::move(args.test_component_svc),
                        .ns = std::move(args.ns),
                        .test_metadata = std::move(args.test_metadata),
                        .request = std::move(controller),
                        .dispatcher = dispatcher_},
      [this](TestComponent* ptr) {
        auto it = test_components_.find(ptr);
        if (it != test_components_.end()) {
          test_components_.erase(it);
        }
      });

  test_components_.emplace(test_component.get(), std::move(test_component));
}
