// 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/storage/fshost/pkgfs-loader-service.h"

#include <fuchsia/io/llcpp/fidl.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/io.h>
#include <lib/syslog/cpp/macros.h>

#include "src/lib/files/path.h"

namespace fio = ::llcpp::fuchsia::io;

namespace devmgr {

// static
std::shared_ptr<PkgfsLoaderService> PkgfsLoaderService::Create(
    fbl::unique_fd blob_dir, std::shared_ptr<FshostBootArgs> boot_args) {
  auto loop = std::make_unique<async::Loop>(&kAsyncLoopConfigNoAttachToCurrentThread);
  loop->StartThread("pkgfs_loader");

  // Can't use make_shared because constructor is private
  return std::shared_ptr<PkgfsLoaderService>(
      new PkgfsLoaderService(std::move(loop), std::move(blob_dir), std::move(boot_args)));
}

zx::status<zx::vmo> PkgfsLoaderService::LoadObjectImpl(std::string path) {
  return LoadPkgfsFile(files::JoinPath("lib", path));
}

zx::status<zx::vmo> PkgfsLoaderService::LoadPkgfsFile(std::string path) {
  auto merkleroot = boot_args_->pkgfs_file_with_path(path);
  if (merkleroot.is_error()) {
    FX_LOGS(ERROR) << "failed to find pkgfs file merkleroot in boot arguments \"" << path << "\"";
    return merkleroot.take_error();
  }

  auto vmo = LoadBlob(merkleroot.value());
  if (vmo.is_error()) {
    FX_LOGS(ERROR) << "failed to load pkgfs file \"" << path << "\": " << vmo.status_string();
    return vmo.take_error();
  }

  auto status = zx::make_status(vmo->set_property(ZX_PROP_NAME, path.c_str(), path.length()));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "failed to set vmo name to " << path << ": " << status.status_string();
    return status.take_error();
  }
  return vmo;
}

zx::status<zx::vmo> PkgfsLoaderService::LoadBlob(std::string merkleroot) {
  const uint32_t kFlags =
      fio::OPEN_FLAG_NOT_DIRECTORY | fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_EXECUTABLE;

  fbl::unique_fd fd;
  zx_status_t status =
      fdio_open_fd_at(blob_dir_.get(), merkleroot.data(), kFlags, fd.reset_and_get_address());
  if (status != ZX_OK) {
    return zx::error(status);
  }

  zx::vmo vmo;
  status = fdio_get_vmo_exec(fd.get(), vmo.reset_and_get_address());
  if (status != ZX_OK) {
    return zx::error(status);
  }
  return zx::ok(std::move(vmo));
}

}  // namespace devmgr
