// 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 "component.h"

#include <dlfcn.h>
#include <fuchsia/mem/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/namespace.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <lib/vfs/cpp/composed_service_dir.h>
#include <lib/vfs/cpp/remote_dir.h>
#include <lib/vfs/cpp/service.h>
#include <sys/stat.h>
#include <zircon/dlfcn.h>
#include <zircon/status.h>
#include <zircon/types.h>

#include <memory>
#include <regex>
#include <sstream>

#include "flutter/fml/mapping.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/unique_fd.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/shell/common/switches.h"
#include "lib/fdio/io.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"

#include "flutter_runner_product_configuration.h"
#include "task_observers.h"
#include "task_runner_adapter.h"
#include "thread.h"

// 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 flutter_runner {

constexpr char kDataKey[] = "data";
constexpr char kAssetsKey[] = "assets";
constexpr char kTmpPath[] = "/tmp";
constexpr char kServiceRootPath[] = "/svc";
constexpr char kRunnerConfigPath[] = "/config/data/flutter_runner_config";

// static
void Application::ParseProgramMetadata(
    const fidl::VectorPtr<fuchsia::sys::ProgramMetadata>& program_metadata,
    std::string* data_path,
    std::string* assets_path) {
  if (!program_metadata.has_value()) {
    return;
  }
  for (const auto& pg : *program_metadata) {
    if (pg.key.compare(kDataKey) == 0) {
      *data_path = "pkg/" + pg.value;
    } else if (pg.key.compare(kAssetsKey) == 0) {
      *assets_path = "pkg/" + pg.value;
    }
  }

  // assets_path defaults to the same as data_path if omitted.
  if (assets_path->empty()) {
    *assets_path = *data_path;
  }
}

// static
ActiveApplication Application::Create(
    TerminationCallback termination_callback,
    fuchsia::sys::Package package,
    fuchsia::sys::StartupInfo startup_info,
    std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
    fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
  std::unique_ptr<Thread> thread = std::make_unique<Thread>();
  std::unique_ptr<Application> application;

  fml::AutoResetWaitableEvent latch;
  async::PostTask(thread->dispatcher(), [&]() mutable {
    application.reset(
        new Application(std::move(termination_callback), std::move(package),
                        std::move(startup_info), runner_incoming_services,
                        std::move(controller)));
    latch.Signal();
  });

  latch.Wait();
  return {.thread = std::move(thread), .application = std::move(application)};
}

static std::string DebugLabelForURL(const std::string& url) {
  auto found = url.rfind("/");
  if (found == std::string::npos) {
    return url;
  } else {
    return {url, found + 1};
  }
}

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

  int fd = 0;
  // The returned file descriptor is compatible with standard posix operations
  // such as close, mmap, etc. We only need to treat open/open_at specially.
  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;
}

// Defaults to readonly. If executable is `true`, we treat it as `read + exec`.
static flutter::MappingCallback MakeDataFileMapping(const char* absolute_path,
                                                    bool executable = false) {
  return [absolute_path, executable = executable](void) {
    return MakeFileMapping(absolute_path, executable);
  };
}

Application::Application(
    TerminationCallback termination_callback,
    fuchsia::sys::Package package,
    fuchsia::sys::StartupInfo startup_info,
    std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
    fidl::InterfaceRequest<fuchsia::sys::ComponentController>
        application_controller_request)
    : termination_callback_(std::move(termination_callback)),
      debug_label_(DebugLabelForURL(startup_info.launch_info.url)),
      application_controller_(this),
      outgoing_dir_(new vfs::PseudoDir()),
      runner_incoming_services_(runner_incoming_services),
      weak_factory_(this) {
  application_controller_.set_error_handler(
      [this](zx_status_t status) { Kill(); });

  FML_DCHECK(fdio_ns_.is_valid());
  // LaunchInfo::url non-optional.
  auto& launch_info = startup_info.launch_info;

  // LaunchInfo::arguments optional.
  if (auto& arguments = launch_info.arguments) {
    settings_.dart_entrypoint_args = arguments.value();
  }

  // Determine where data and assets are stored within /pkg.
  std::string data_path;
  std::string assets_path;
  ParseProgramMetadata(startup_info.program_metadata, &data_path, &assets_path);

  if (data_path.empty()) {
    FML_DLOG(ERROR) << "Could not find a /pkg/data directory for "
                    << package.resolved_url;
    return;
  }

  // Setup /tmp to be mapped to the process-local memfs.
  dart_utils::RunnerTemp::SetupComponent(fdio_ns_.get());

  // LaunchInfo::flat_namespace optional.
  for (size_t i = 0; i < startup_info.flat_namespace.paths.size(); ++i) {
    const auto& path = startup_info.flat_namespace.paths.at(i);
    if (path == kTmpPath) {
      continue;
    }

    zx::channel dir;
    if (path == kServiceRootPath) {
      svc_ = std::make_unique<sys::ServiceDirectory>(
          std::move(startup_info.flat_namespace.directories.at(i)));
      dir = svc_->CloneChannel().TakeChannel();
    } else {
      dir = std::move(startup_info.flat_namespace.directories.at(i));
    }

    zx_handle_t dir_handle = dir.release();
    if (fdio_ns_bind(fdio_ns_.get(), path.data(), dir_handle) != ZX_OK) {
      FML_DLOG(ERROR) << "Could not bind path to namespace: " << path;
      zx_handle_close(dir_handle);
    }
  }

  {
    fml::UniqueFD ns_fd(fdio_ns_opendir(fdio_ns_.get()));
    FML_DCHECK(ns_fd.is_valid());

    constexpr mode_t mode = O_RDONLY | O_DIRECTORY;

    application_assets_directory_.reset(
        openat(ns_fd.get(), assets_path.c_str(), mode));
    FML_DCHECK(application_assets_directory_.is_valid());

    application_data_directory_.reset(
        openat(ns_fd.get(), data_path.c_str(), mode));
    FML_DCHECK(application_data_directory_.is_valid());
  }

  // TODO: LaunchInfo::out.

  // TODO: LaunchInfo::err.

  // LaunchInfo::service_request optional.
  if (launch_info.directory_request) {
    outgoing_dir_->Serve(fuchsia::io::OPEN_RIGHT_READABLE |
                             fuchsia::io::OPEN_RIGHT_WRITABLE |
                             fuchsia::io::OPEN_FLAG_DIRECTORY,
                         std::move(launch_info.directory_request));
  }

  directory_request_ = directory_ptr_.NewRequest();

  fidl::InterfaceHandle<fuchsia::io::Directory> flutter_public_dir;
  // TODO(anmittal): when fixing enumeration using new c++ vfs, make sure that
  // flutter_public_dir is only accessed once we receive OnOpen Event.
  // That will prevent FL-175 for public directory
  auto request = flutter_public_dir.NewRequest().TakeChannel();
  fdio_service_connect_at(directory_ptr_.channel().get(), "svc",
                          request.release());

  auto composed_service_dir = std::make_unique<vfs::ComposedServiceDir>();
  composed_service_dir->set_fallback(std::move(flutter_public_dir));

  // Clone and check if client is servicing the directory.
  directory_ptr_->Clone(fuchsia::io::OPEN_FLAG_DESCRIBE |
                            fuchsia::io::OPEN_RIGHT_READABLE |
                            fuchsia::io::OPEN_RIGHT_WRITABLE,
                        cloned_directory_ptr_.NewRequest());

  cloned_directory_ptr_.events().OnOpen =
      [this](zx_status_t status, std::unique_ptr<fuchsia::io::NodeInfo> info) {
        cloned_directory_ptr_.Unbind();
        if (status != ZX_OK) {
          FML_LOG(ERROR) << "could not bind out directory for flutter app("
                         << debug_label_
                         << "): " << zx_status_get_string(status);
          return;
        }
        const char* other_dirs[] = {"debug", "ctrl", "diagnostics"};
        // add other directories as RemoteDirs.
        for (auto& dir_str : other_dirs) {
          fidl::InterfaceHandle<fuchsia::io::Directory> dir;
          auto request = dir.NewRequest().TakeChannel();
          auto status = fdio_service_connect_at(directory_ptr_.channel().get(),
                                                dir_str, request.release());
          if (status == ZX_OK) {
            outgoing_dir_->AddEntry(
                dir_str, std::make_unique<vfs::RemoteDir>(dir.TakeChannel()));
          } else {
            FML_LOG(ERROR) << "could not add out directory entry(" << dir_str
                           << ") for flutter app(" << debug_label_
                           << "): " << zx_status_get_string(status);
          }
        }
      };

  cloned_directory_ptr_.set_error_handler(
      [this](zx_status_t status) { cloned_directory_ptr_.Unbind(); });

  // TODO: LaunchInfo::additional_services optional.

  // All launch arguments have been read. Perform service binding and
  // final settings configuration. The next call will be to create a view
  // for this application.
  composed_service_dir->AddService(
      fuchsia::ui::app::ViewProvider::Name_,
      std::make_unique<vfs::Service>(
          [this](zx::channel channel, async_dispatcher_t* dispatcher) {
            shells_bindings_.AddBinding(
                this, fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(
                          std::move(channel)));
          }));

  outgoing_dir_->AddEntry("svc", std::move(composed_service_dir));

  // Setup the application controller binding.
  if (application_controller_request) {
    application_controller_.Bind(std::move(application_controller_request));
  }

  // Compare flutter_jit_runner in BUILD.gn.
  settings_.vm_snapshot_data =
      MakeDataFileMapping("/pkg/data/vm_snapshot_data.bin");
  settings_.vm_snapshot_instr =
      MakeDataFileMapping("/pkg/data/vm_snapshot_instructions.bin", true);

  settings_.isolate_snapshot_data =
      MakeDataFileMapping("/pkg/data/isolate_core_snapshot_data.bin");
  settings_.isolate_snapshot_instr = MakeDataFileMapping(
      "/pkg/data/isolate_core_snapshot_instructions.bin", true);

  {
    // Check if we can use the snapshot with the framework already loaded.
    std::string runner_framework;
    std::string app_framework;
    if (dart_utils::ReadFileToString("pkg/data/runner.frameworkversion",
                                     &runner_framework) &&
        dart_utils::ReadFileToStringAt(application_data_directory_.get(),
                                       "app.frameworkversion",
                                       &app_framework) &&
        (runner_framework.compare(app_framework) == 0)) {
      settings_.vm_snapshot_data =
          MakeDataFileMapping("/pkg/data/framework_vm_snapshot_data.bin");
      settings_.vm_snapshot_instr =
          MakeDataFileMapping("/pkg/data/vm_snapshot_instructions.bin", true);

      settings_.isolate_snapshot_data = MakeDataFileMapping(
          "/pkg/data/framework_isolate_core_snapshot_data.bin");
      settings_.isolate_snapshot_instr = MakeDataFileMapping(
          "/pkg/data/isolate_core_snapshot_instructions.bin", true);

      FML_LOG(INFO) << "Using snapshot with framework for "
                    << package.resolved_url;
    } else {
      FML_LOG(INFO) << "Using snapshot without framework for "
                    << package.resolved_url;
    }
  }

  // Load and use runner-specific configuration, if it exists.
  std::string json_string;
  if (dart_utils::ReadFileToString(kRunnerConfigPath, &json_string)) {
    product_config_ = FlutterRunnerProductConfiguration(json_string);
  } else {
    FML_LOG(WARNING) << "Failed to load runner configuration from "
                     << kRunnerConfigPath << "; using default config values.";
  }

#if defined(DART_PRODUCT)
  settings_.enable_observatory = false;
#else
  settings_.enable_observatory = true;

  // TODO(cbracken): pass this in as a param to allow 0.0.0.0, ::1, etc.
  settings_.observatory_host = "127.0.0.1";
#endif

  // Controls whether category "skia" trace events are enabled.
  settings_.trace_skia = true;

  settings_.verbose_logging = true;

  settings_.advisory_script_uri = debug_label_;

  settings_.advisory_script_entrypoint = debug_label_;

  settings_.icu_data_path = "";

  settings_.assets_dir = application_assets_directory_.get();

  // Compare flutter_jit_app in flutter_app.gni.
  settings_.application_kernel_list_asset = "app.dilplist";

  settings_.log_tag = debug_label_ + std::string{"(flutter)"};

  // No asserts in debug or release product.
  // No asserts in release with flutter_profile=true (non-product)
  // Yes asserts in non-product debug.
#if !defined(DART_PRODUCT) && (!defined(FLUTTER_PROFILE) || !defined(NDEBUG))
  // Debug mode
  settings_.disable_dart_asserts = false;
#else
  // Release mode
  settings_.disable_dart_asserts = true;
#endif

  settings_.task_observer_add =
      std::bind(&CurrentMessageLoopAddAfterTaskObserver, std::placeholders::_1,
                std::placeholders::_2);

  settings_.task_observer_remove = std::bind(
      &CurrentMessageLoopRemoveAfterTaskObserver, std::placeholders::_1);

  // TODO(FL-117): Re-enable causal async stack traces when this issue is
  // addressed.
  settings_.dart_flags = {"--no_causal_async_stacks"};

  // Don't collect CPU samples from Dart VM C++ code.
  settings_.dart_flags.push_back("--no_profile_vm");

  // Scale back CPU profiler sampling period on ARM64 to avoid overloading
  // the tracing engine.
#if defined(__aarch64__)
  settings_.dart_flags.push_back("--profile_period=10000");
#endif  // defined(__aarch64__)

  auto weak_application = weak_factory_.GetWeakPtr();
  auto platform_task_runner =
      CreateFMLTaskRunner(async_get_default_dispatcher());
  const std::string component_url = package.resolved_url;
  settings_.unhandled_exception_callback = [weak_application,
                                            platform_task_runner,
                                            runner_incoming_services,
                                            component_url](
                                               const std::string& error,
                                               const std::string& stack_trace) {
    if (weak_application) {
      // TODO(cbracken): unsafe. The above check and the PostTask below are
      // happening on the UI thread. If the Application dtor and thread
      // termination happen (on the platform thread) between the previous
      // line and the next line, a crash will occur since we'll be posting
      // to a dead thread. See Runner::OnApplicationTerminate() in
      // runner.cc.
      platform_task_runner->PostTask([weak_application,
                                      runner_incoming_services, component_url,
                                      error, stack_trace]() {
        if (weak_application) {
          dart_utils::HandleException(runner_incoming_services, component_url,
                                      error, stack_trace);
        } else {
          FML_LOG(WARNING)
              << "Exception was thrown which was not caught in Flutter app: "
              << error;
        }
      });
    } else {
      FML_LOG(WARNING)
          << "Exception was thrown which was not caught in Flutter app: "
          << error;
    }
    // Ideally we would return whether HandleException returned ZX_OK, but
    // short of knowing if the exception was correctly handled, we return
    // false to have the error and stack trace printed in the logs.
    return false;
  };

  AttemptVMLaunchWithCurrentSettings(settings_);
}

Application::~Application() = default;

const std::string& Application::GetDebugLabel() const {
  return debug_label_;
}

class FileInNamespaceBuffer final : public fml::Mapping {
 public:
  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)) {
      return;
    }
    if (buffer.size == 0) {
      return;
    }

    uint32_t flags = ZX_VM_PERM_READ;
    if (executable) {
      flags |= ZX_VM_PERM_EXECUTE;
    }
    uintptr_t addr;
    zx_status_t status =
        zx::vmar::root_self()->map(0, buffer.vmo, 0, buffer.size, flags, &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() {
    if (address_ != nullptr) {
      zx::vmar::root_self()->unmap(reinterpret_cast<uintptr_t>(address_),
                                   size_);
      address_ = nullptr;
      size_ = 0;
    }
  }

  // |fml::Mapping|
  const uint8_t* GetMapping() const override {
    return reinterpret_cast<const uint8_t*>(address_);
  }

  // |fml::Mapping|
  size_t GetSize() const override { return size_; }

 private:
  void* address_;
  size_t size_;

  FML_DISALLOW_COPY_AND_ASSIGN(FileInNamespaceBuffer);
};

std::unique_ptr<fml::Mapping> CreateWithContentsOfFile(int namespace_fd,
                                                       const char* file_path,
                                                       bool executable) {
  FML_TRACE_EVENT("flutter", "LoadFile", "path", file_path);
  auto source = std::make_unique<FileInNamespaceBuffer>(namespace_fd, file_path,
                                                        executable);
  return source->GetMapping() == nullptr ? nullptr : std::move(source);
}

void Application::AttemptVMLaunchWithCurrentSettings(
    const flutter::Settings& settings) {
  if (!flutter::DartVM::IsRunningPrecompiledCode()) {
    // We will be initializing the VM lazily in this case.
    return;
  }

  // Compare with flutter_aot_app in flutter_app.gni.
  fml::RefPtr<flutter::DartSnapshot> vm_snapshot;

  std::shared_ptr<dart_utils::ElfSnapshot> snapshot =
      std::make_shared<dart_utils::ElfSnapshot>();
  if (snapshot->Load(application_data_directory_.get(),
                     "app_aot_snapshot.so")) {
    const uint8_t* isolate_data = snapshot->IsolateData();
    const uint8_t* isolate_instructions = snapshot->IsolateInstrs();
    const uint8_t* vm_data = snapshot->VmData();
    const uint8_t* vm_instructions = snapshot->VmInstrs();
    if (isolate_data == nullptr || isolate_instructions == nullptr ||
        vm_data == nullptr || vm_instructions == nullptr) {
      FML_LOG(FATAL) << "ELF snapshot missing AOT symbols.";
      return;
    }
    auto hold_snapshot = [snapshot](const uint8_t* _, size_t __) {};
    vm_snapshot = fml::MakeRefCounted<flutter::DartSnapshot>(
        std::make_shared<fml::NonOwnedMapping>(vm_data, 0, hold_snapshot),
        std::make_shared<fml::NonOwnedMapping>(vm_instructions, 0,
                                               hold_snapshot));
    isolate_snapshot_ = fml::MakeRefCounted<flutter::DartSnapshot>(
        std::make_shared<fml::NonOwnedMapping>(isolate_data, 0, hold_snapshot),
        std::make_shared<fml::NonOwnedMapping>(isolate_instructions, 0,
                                               hold_snapshot));
  } else {
    vm_snapshot = fml::MakeRefCounted<flutter::DartSnapshot>(
        CreateWithContentsOfFile(application_data_directory_.get(),
                                 "vm_snapshot_data.bin", false),
        CreateWithContentsOfFile(application_data_directory_.get(),
                                 "vm_snapshot_instructions.bin", true));

    isolate_snapshot_ = fml::MakeRefCounted<flutter::DartSnapshot>(
        CreateWithContentsOfFile(application_data_directory_.get(),
                                 "isolate_snapshot_data.bin", false),
        CreateWithContentsOfFile(application_data_directory_.get(),
                                 "isolate_snapshot_instructions.bin", true));
  }

  auto vm = flutter::DartVMRef::Create(settings_,               //
                                       std::move(vm_snapshot),  //
                                       isolate_snapshot_        //
  );
  FML_CHECK(vm) << "Mut be able to initialize the VM.";
}

void Application::Kill() {
  application_controller_.events().OnTerminated(
      last_return_code_.second, fuchsia::sys::TerminationReason::EXITED);

  termination_callback_(this);
  // WARNING: Don't do anything past this point as this instance may have been
  // collected.
}

void Application::Detach() {
  application_controller_.set_error_handler(nullptr);
}

void Application::OnEngineTerminate(const Engine* shell_holder) {
  auto found = std::find_if(shell_holders_.begin(), shell_holders_.end(),
                            [shell_holder](const auto& holder) {
                              return holder.get() == shell_holder;
                            });

  if (found == shell_holders_.end()) {
    return;
  }

  // We may launch multiple shell in this application. However, we will
  // terminate when the last shell goes away. The error code return to the
  // application controller will be the last isolate that had an error.
  auto return_code = shell_holder->GetEngineReturnCode();
  if (return_code.first) {
    last_return_code_ = return_code;
  }

  shell_holders_.erase(found);

  if (shell_holders_.size() == 0) {
    Kill();
    // WARNING: Don't do anything past this point because the delegate may have
    // collected this instance via the termination callback.
  }
}

void Application::CreateView(
    zx::eventpair token,
    fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> /*incoming_services*/,
    fidl::InterfaceHandle<
        fuchsia::sys::ServiceProvider> /*outgoing_services*/) {
  auto view_ref_pair = scenic::ViewRefPair::New();
  CreateViewWithViewRef(std::move(token), std::move(view_ref_pair.control_ref),
                        std::move(view_ref_pair.view_ref));
}

void Application::CreateViewWithViewRef(
    zx::eventpair view_token,
    fuchsia::ui::views::ViewRefControl control_ref,
    fuchsia::ui::views::ViewRef view_ref) {
  if (!svc_) {
    FML_DLOG(ERROR)
        << "Component incoming services was invalid when attempting to "
           "create a shell for a view provider request.";
    return;
  }

  shell_holders_.emplace(std::make_unique<Engine>(
      *this,                         // delegate
      debug_label_,                  // thread label
      svc_,                          // Component incoming services
      runner_incoming_services_,     // Runner incoming services
      settings_,                     // settings
      std::move(isolate_snapshot_),  // isolate snapshot
      scenic::ToViewToken(std::move(view_token)),  // view token
      scenic::ViewRefPair{
          .control_ref = std::move(control_ref),
          .view_ref = std::move(view_ref),
      },
      std::move(fdio_ns_),            // FDIO namespace
      std::move(directory_request_),  // outgoing request
      product_config_                 // product configuration
      ));
}

#if !defined(DART_PRODUCT)
void Application::WriteProfileToTrace() const {
  for (const auto& engine : shell_holders_) {
    engine->WriteProfileToTrace();
  }
}
#endif  // !defined(DART_PRODUCT)

}  // namespace flutter_runner
