// 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/lib/loader/package_loader.h"

#include <fcntl.h>
#include <trace/event.h>
#include <zircon/status.h>

#include <utility>

#include "lib/fidl/cpp/optional.h"
#include "lib/fsl/io/fd.h"
#include "lib/fsl/vmo/file.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/strings/substitute.h"
#include "lib/pkg_url/url_resolver.h"

namespace component {

PackageLoader::PackageLoader() = default;
PackageLoader::~PackageLoader() = default;

void PackageLoader::LoadUrl(fidl::StringPtr url, LoadUrlCallback callback) {
  TRACE_DURATION("appmgr", "PackageLoader::LoadUrl", "url", url.get());

  // package is our result. We're going to build it up iteratively.
  fuchsia::sys::Package package;

  // First we are going to resolve the package directory, if it is present. We
  // can't handle resources yet, because we may not have enough URL to do so.
  FuchsiaPkgUrl fuchsia_url;
  bool parsed = false;

  if (FuchsiaPkgUrl::IsFuchsiaPkgScheme(url)) {
    parsed = fuchsia_url.Parse(url);
  } else {
    parsed =
        fuchsia_url.Parse("fuchsia-pkg://fuchsia.com/" + GetPathFromURL(url));
  }

  // If the url isn't valid after our attempt at fix-up, bail.
  if (!parsed) {
    FXL_LOG(ERROR) << "Cannot load " << url << " because the URL is not valid.";
    callback(nullptr);
    return;
  }

  package.resolved_url = fuchsia_url.ToString();
  // TODO(CF-156): Remove support for non fuchsia-pkg URLs, and get rid of this.
  if (!FuchsiaPkgUrl::IsFuchsiaPkgScheme(url)) {
    FXL_LOG(WARNING)
        << "Component " << url
        << " was launched without using fuchsia-pkg URLs! Use "
        << package.resolved_url << "#"
        << fuchsia_url.GetDefaultComponentCmxPath()
        << " instead. See https://fuchsia.googlesource.com/docs/+/master/"
        << "glossary.md#fuchsia_pkg-url for more information.";
  }

  fxl::UniqueFD package_dir(
      open(fuchsia_url.pkgfs_dir_path().c_str(), O_DIRECTORY | O_RDONLY));
  if (!package_dir.is_valid()) {
    FXL_LOG(ERROR) << "Could not open directory "
                   << fuchsia_url.pkgfs_dir_path() << " " << strerror(errno);
    callback(nullptr);
    return;
  }

  // Why does this method have un-reportable error conditions?
  zx::channel directory =
      fsl::CloneChannelFromFileDescriptor(package_dir.get());
  if (!directory) {
    FXL_LOG(ERROR) << "Could not clone directory "
                   << fuchsia_url.pkgfs_dir_path();
    callback(nullptr);
    return;
  }
  package.directory = std::move(directory);

  if (!fuchsia_url.resource_path().empty()) {
    if (!LoadResource(package_dir, fuchsia_url.resource_path(), package)) {
      FXL_LOG(ERROR) << "Could not load package resource "
                     << fuchsia_url.resource_path() << " from " << url;
      callback(nullptr);
      return;
    }
  }

  callback(fidl::MakeOptional(std::move(package)));
}

void PackageLoader::AddBinding(
    fidl::InterfaceRequest<fuchsia::sys::Loader> request) {
  bindings_.AddBinding(this, std::move(request));
}

bool PackageLoader::LoadResource(const fxl::UniqueFD& dir,
                                 const std::string path,
                                 fuchsia::sys::Package& package) {
  fsl::SizedVmo resource;
  if (!fsl::VmoFromFilenameAt(dir.get(), path, &resource)) {
    return false;
  }

  resource.vmo().set_property(ZX_PROP_NAME, path.c_str(), path.length());
  package.data = fidl::MakeOptional(std::move(resource).ToTransport());

  return true;
}

}  // namespace component
