// 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, 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, callback);
    return;
  }

  fuchsia::io::DirectoryPtr dir;
  auto dir_request = dir.NewRequest(dispatcher_);
  auto done_cb = [this, url, dir = std::move(dir),
                  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, 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
