// 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 "garnet/bin/sysmgr/package_updating_loader.h"

#include <fcntl.h>
#include <string>
#include <utility>

#include <fuchsia/io/cpp/fidl.h>
#include <lib/fit/function.h>
#include <zircon/errors.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#include "lib/fidl/cpp/optional.h"
#include "lib/fsl/io/fd.h"
#include "lib/fsl/vmo/file.h"
#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/strings/substitute.h"
#include "lib/pkg_url/url_resolver.h"
#include "lib/svc/cpp/services.h"

namespace sysmgr {

PackageUpdatingLoader::PackageUpdatingLoader(
    std::unordered_set<std::string> update_dependency_urls,
    fuchsia::sys::ServiceProviderPtr service_provider,
    async_dispatcher_t* dispatcher)
    : update_dependency_urls_(std::move(update_dependency_urls)),
      service_provider_(std::move(service_provider)),
      dispatcher_(dispatcher),
      needs_reconnect_(true) {
  EnsureConnectedToResolver();
}

PackageUpdatingLoader::~PackageUpdatingLoader() = default;

void PackageUpdatingLoader::LoadUrl(std::string url, LoadUrlCallback callback) {
  EnsureConnectedToResolver();

  // The updating loader can only update fuchsia-pkg URLs.
  component::FuchsiaPkgUrl fuchsia_url;
  bool parsed = false;
  if (component::FuchsiaPkgUrl::IsFuchsiaPkgScheme(url)) {
    parsed = fuchsia_url.Parse(url);
  } else {
    parsed = fuchsia_url.Parse("fuchsia-pkg://fuchsia.com/" +
                               component::GetPathFromURL(url));
  }
  if (!parsed) {
    PackageLoader::LoadUrl(url, std::move(callback));
    return;
  }

  // Avoid infinite reentry and cycles: Don't attempt to update the package
  // resolver or any dependent package. Contacting the package resolver may
  // require starting its component or a dependency, which would end up back
  // here.
  if (std::find(update_dependency_urls_.begin(), update_dependency_urls_.end(),
                url) != std::end(update_dependency_urls_)) {
    PackageLoader::LoadUrl(url, std::move(callback));
    return;
  }

  fuchsia::io::DirectoryPtr dir;
  auto dir_request = dir.NewRequest(dispatcher_);
  auto done_cb = [this, url, dir = std::move(dir),
                  callback = std::move(callback)](zx_status_t status) mutable {
    // TODO: only fail soft on NOT_FOUND?
    if (status != ZX_OK) {
      FXL_VLOG(1) << "Package update failed with "
                  << zx_status_get_string(status)
                  << ". Loading package without update: " << url;
    }
    PackageLoader::LoadUrl(url, std::move(callback));
  };

  fuchsia::pkg::UpdatePolicy update_policy;
  update_policy.fetch_if_absent = true;
  fidl::VectorPtr<std::string> selectors;
  selectors.reset({});

  // TODO: if the resolver became unavailable in between the start of this
  // method and the following call to Resolve, our reconnection logic won't have
  // had a chance to execute, so we'll still block our client's request
  // indefinitely. to resolve this we'll maybe need to change the API or undergo
  // some more significant refactoring.
  resolver_->Resolve(fuchsia_url.package_path(), std::move(selectors),
                     std::move(update_policy), std::move(dir_request),
                     std::move(done_cb));
}

void PackageUpdatingLoader::EnsureConnectedToResolver() {
  if (needs_reconnect_) {
    service_provider_->ConnectToService(fuchsia::pkg::PackageResolver::Name_,
                                        resolver_.NewRequest().TakeChannel());

    // the error handler is consumed when an error is encountered, so if we
    // need to reconnect then it means we need to reinstall the handler too
    resolver_.set_error_handler([this](zx_status_t status) {
      FXL_LOG(ERROR) << "Package resolver error handler triggered, marking as "
                        "needing reconnect. status="
                     << status;
      needs_reconnect_ = true;
    });

    needs_reconnect_ = false;
  }
}

}  // namespace sysmgr
