// Copyright 2013 The Flutter 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 "file_in_namespace_buffer.h"

#include <lib/fdio/directory.h>
#include <zircon/status.h>

#include "flutter/fml/trace_event.h"
#include "runtime/dart/utils/files.h"
#include "runtime/dart/utils/handle_exception.h"
#include "runtime/dart/utils/mapped_resource.h"
#include "runtime/dart/utils/tempfs.h"
#include "runtime/dart/utils/vmo.h"

namespace flutter_runner {

namespace {

// TODO(kaushikiska): Use these constants from ::llcpp::fuchsia::io
// Can read from target object.
constexpr uint32_t OPEN_RIGHT_READABLE = 1u;

// Connection can map target object executable.
constexpr uint32_t OPEN_RIGHT_EXECUTABLE = 8u;

}  // namespace

FileInNamespaceBuffer::FileInNamespaceBuffer(int namespace_fd,
                                             const char* path,
                                             bool executable)
    : address_(nullptr), size_(0) {
  fuchsia::mem::Buffer buffer;
  if (!dart_utils::VmoFromFilenameAt(namespace_fd, path, executable, &buffer) ||
      buffer.size == 0) {
    return;
  }

  uint32_t flags = ZX_VM_PERM_READ;
  if (executable) {
    flags |= ZX_VM_PERM_EXECUTE;
  }

  uintptr_t addr;
  const zx_status_t status =
      zx::vmar::root_self()->map(flags, 0, buffer.vmo, 0, buffer.size, &addr);
  if (status != ZX_OK) {
    FML_LOG(FATAL) << "Failed to map " << path << ": "
                   << zx_status_get_string(status);
  }

  address_ = reinterpret_cast<void*>(addr);
  size_ = buffer.size;
}

FileInNamespaceBuffer::~FileInNamespaceBuffer() {
  if (address_ != nullptr) {
    zx::vmar::root_self()->unmap(reinterpret_cast<uintptr_t>(address_), size_);
    address_ = nullptr;
    size_ = 0;
  }
}

const uint8_t* FileInNamespaceBuffer::GetMapping() const {
  return reinterpret_cast<const uint8_t*>(address_);
}

size_t FileInNamespaceBuffer::GetSize() const {
  return size_;
}

bool FileInNamespaceBuffer::IsDontNeedSafe() const {
  return true;
}

std::unique_ptr<fml::Mapping> LoadFile(int namespace_fd,
                                       const char* path,
                                       bool executable) {
  FML_TRACE_EVENT("flutter", "LoadFile", "path", path);
  return std::make_unique<FileInNamespaceBuffer>(namespace_fd, path,
                                                 executable);
}

std::unique_ptr<fml::FileMapping> MakeFileMapping(const char* path,
                                                  bool executable) {
  uint32_t flags = OPEN_RIGHT_READABLE;
  if (executable) {
    flags |= OPEN_RIGHT_EXECUTABLE;
  }

  // The returned file descriptor is compatible with standard posix operations
  // such as close, mmap, etc. We only need to treat open/open_at specially.
  int fd;
  const zx_status_t status = fdio_open_fd(path, flags, &fd);
  if (status != ZX_OK) {
    return nullptr;
  }

  using Protection = fml::FileMapping::Protection;

  std::initializer_list<Protection> protection_execute = {Protection::kRead,
                                                          Protection::kExecute};
  std::initializer_list<Protection> protection_read = {Protection::kRead};
  auto mapping = std::make_unique<fml::FileMapping>(
      fml::UniqueFD{fd}, executable ? protection_execute : protection_read);

  if (!mapping->IsValid()) {
    return nullptr;
  }
  return mapping;
}

}  // namespace flutter_runner
