// Copyright 2020 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/sys/run_test_component/component.h"

#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/fdio/fd.h>
#include <lib/fpromise/barrier.h>
#include <lib/fpromise/promise.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/handle.h>
#include <unistd.h>
#include <zircon/processargs.h>

#include <memory>

#include <fbl/unique_fd.h>

#include "src/sys/run_test_component/output_collector.h"

namespace run {

namespace {

void AddOutputFileDescriptor(int fileno, FILE* out_file, async_dispatcher_t* dispatcher,
                             std::unique_ptr<OutputCollector>* out_output_collector,
                             fuchsia::sys::FileDescriptorPtr* out_file_descriptor) {
  auto output_collector = OutputCollector::Create();
  fuchsia::sys::FileDescriptorPtr file_descriptor =
      std::make_unique<fuchsia::sys::FileDescriptor>();
  file_descriptor->type0 = PA_HND(PA_FD, fileno);
  file_descriptor->handle0 = output_collector->TakeServer();
  *out_file_descriptor = std::move(file_descriptor);
  output_collector->CollectOutput(
      [out_file, dispatcher](std::string s) {
        async::PostTask(dispatcher, [s = std::move(s), out_file]() {
          // don't use fprintf as that truncates the output on first zero.
          fwrite(s.data(), 1, s.length(), out_file);
          fflush(out_file);
        });
      },
      dispatcher);

  *out_output_collector = std::move(output_collector);
}

}  // namespace

std::unique_ptr<Component> Component::Launch(const fuchsia::sys::LauncherPtr& launcher,
                                             fuchsia::sys::LaunchInfo launch_info,
                                             async_dispatcher_t* dispatcher) {
  std::unique_ptr<OutputCollector> out, err;

  if (!launch_info.out) {
    AddOutputFileDescriptor(STDOUT_FILENO, stdout, dispatcher, &out, &launch_info.out);
  }

  if (!launch_info.err) {
    AddOutputFileDescriptor(STDERR_FILENO, stderr, dispatcher, &err, &launch_info.err);
  }

  auto svc = sys::ServiceDirectory::CreateWithRequest(&launch_info.directory_request);
  fuchsia::sys::ComponentControllerPtr contoller;
  launcher->CreateComponent(std::move(launch_info), contoller.NewRequest());
  return std::make_unique<Component>(std::move(out), std::move(err), std::move(contoller),
                                     std::move(svc));
}

fpromise::promise<> Component::SignalWhenOutputCollected() {
  return stderr_->SignalWhenDone().and_then(stdout_->SignalWhenDone());
}

Component::Component(std::unique_ptr<OutputCollector> out, std::unique_ptr<OutputCollector> err,
                     fuchsia::sys::ComponentControllerPtr controller,
                     std::shared_ptr<sys::ServiceDirectory> svc)
    : stdout_(std::move(out)),
      stderr_(std::move(err)),
      controller_(std::move(controller)),
      svc_(std::move(svc)) {}

}  // namespace run
