// Copyright 2019 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/appmgr/log_connector_impl.h"

#include <lib/async/cpp/task.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/syslog/global.h>

#include "src/lib/fsl/handles/object_info.h"
#include "src/sys/appmgr/util.h"

namespace component {

namespace {

void SetUpSyslogOnce(const fuchsia::sys::internal::LogConnectionListenerPtr& listener) {
  // No other component runs until Archivist is launched so the first time we have a listener it
  // must be Archivist.
  static bool syslog_configured = false;
  if (syslog_configured)
    return;
  syslog_configured = true;

  fuchsia::logger::LogSinkPtr log_sink;
  fidl::InterfaceRequest<fuchsia::logger::LogSink> request = log_sink.NewRequest();
  if (!request) {
    FX_LOGS(WARNING) << "Failed to create a LogSink channel. Appmgr can't use syslog.";
    return;
  }

  fuchsia::sys::internal::SourceIdentity identity;
  identity.set_component_url("fuchsia-pkg://fuchsia.com/appmgr#meta/appmgr.cm");
  identity.set_component_name("appmgr");
  identity.set_realm_path({});
  identity.set_instance_id(std::to_string(fsl::GetCurrentProcessKoid()));

  listener->OnNewConnection({
      .log_request = std::move(request),
      .source_identity = std::move(identity),
  });

  zx::socket local, remote;
  if (zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote) != ZX_OK) {
    FX_LOGS(WARNING) << "Failed to create a socket. Appmgr can't use syslog.";
    return;
  }
  log_sink->Connect(std::move(remote));

  const char* tag = "appmgr";
  fx_logger_config_t config = {.min_severity = FX_LOG_INFO,
                               .console_fd = -1,
                               .log_service_channel = local.release(),
                               .tags = &tag,
                               .num_tags = 1};
  if (fx_log_reconfigure(&config) != ZX_OK) {
    FX_LOGS(WARNING) << "Failed to reconfigure syslog";
    return;
  }

  FX_LOGS(INFO) << "Successfully set up syslog";
}
}  // namespace

LogConnectorImpl::LogConnectorImpl(fxl::WeakPtr<LogConnectorImpl> parent, std::string realm_label)
    : parent_(std::move(parent)),
      realm_label_(realm_label),
      consumer_request_(consumer_.NewRequest()),
      weak_factory_(this){};

LogConnectorImpl::LogConnectorImpl(std::string realm_label)
    : LogConnectorImpl(nullptr /* parent */, realm_label) {}

fbl::RefPtr<LogConnectorImpl> LogConnectorImpl::NewChild(std::string child_realm_label) {
  auto child = new LogConnectorImpl(weak_factory_.GetWeakPtr(), child_realm_label);
  return AdoptRef(child);
}

void LogConnectorImpl::TakeLogConnectionListener(TakeLogConnectionListenerCallback callback) {
  FX_LOGS(INFO) << "taking log connector for " << realm_label_;
  callback(std::move(consumer_request_));
  // This once-callback will be set only for the root "app" realm and it will be
  // available because it is set before we run the event loop.
  if (on_ready_) {
    (*on_ready_)();
    on_ready_.reset();
  }
  SetUpSyslogOnce(consumer_);
}

void LogConnectorImpl::OnReady(fit::function<void()> on_ready) { on_ready_ = std::move(on_ready); }

void LogConnectorImpl::AddConnectorClient(
    fidl::InterfaceRequest<fuchsia::sys::internal::LogConnector> request) {
  bindings_.AddBinding(this, std::move(request));
}

void LogConnectorImpl::AddLogConnection(
    std::string component_url, std::string instance_id,
    fidl::InterfaceRequest<fuchsia::logger::LogSink> connection) {
  // find the nearest initialized LogConnector, assumes that >=1 one is instantiated before this
  std::vector<std::string> realm_path;
  auto current = this;
  while (current->parent_ && current->consumer_request_.is_valid()) {
    realm_path.push_back(current->realm_label_);
    current = &*current->parent_;
  }
  std::reverse(realm_path.begin(), realm_path.end());

  auto component_name = Util::GetLabelFromURL(component_url);
  fuchsia::sys::internal::SourceIdentity identity;
  identity.set_instance_id(instance_id);
  identity.set_realm_path(realm_path);
  identity.set_component_url(std::move(component_url));
  identity.set_component_name(std::move(component_name));

  current->consumer_->OnNewConnection({
      .log_request = std::move(connection),
      .source_identity = std::move(identity),
  });
}
}  // namespace component
