// 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 "flutter/runtime/isolate_configuration.h"

#include "flutter/fml/make_copyable.h"
#include "flutter/runtime/dart_vm.h"

namespace flutter {

IsolateConfiguration::IsolateConfiguration() = default;

IsolateConfiguration::~IsolateConfiguration() = default;

bool IsolateConfiguration::PrepareIsolate(DartIsolate& isolate) {
  if (isolate.GetPhase() != DartIsolate::Phase::LibrariesSetup) {
    FML_DLOG(ERROR)
        << "Isolate was in incorrect phase to be prepared for running.";
    return false;
  }

  return DoPrepareIsolate(isolate);
}

class AppSnapshotIsolateConfiguration final : public IsolateConfiguration {
 public:
  AppSnapshotIsolateConfiguration() = default;

  // |IsolateConfiguration|
  bool DoPrepareIsolate(DartIsolate& isolate) override {
    return isolate.PrepareForRunningFromPrecompiledCode();
  }

  // |IsolateConfiguration|
  bool IsNullSafetyEnabled(const DartSnapshot& snapshot) override {
    return snapshot.IsNullSafetyEnabled(nullptr);
  }

 private:
  FML_DISALLOW_COPY_AND_ASSIGN(AppSnapshotIsolateConfiguration);
};

class KernelIsolateConfiguration : public IsolateConfiguration {
 public:
  explicit KernelIsolateConfiguration(
      std::unique_ptr<const fml::Mapping> kernel)
      : kernel_(std::move(kernel)) {}

  // |IsolateConfiguration|
  bool DoPrepareIsolate(DartIsolate& isolate) override {
    if (DartVM::IsRunningPrecompiledCode()) {
      return false;
    }
    return isolate.PrepareForRunningFromKernel(std::move(kernel_),
                                               /*child_isolate=*/false,
                                               /*last_piece=*/true);
  }

  // |IsolateConfiguration|
  bool IsNullSafetyEnabled(const DartSnapshot& snapshot) override {
    return snapshot.IsNullSafetyEnabled(kernel_.get());
  }

 private:
  std::unique_ptr<const fml::Mapping> kernel_;

  FML_DISALLOW_COPY_AND_ASSIGN(KernelIsolateConfiguration);
};

class KernelListIsolateConfiguration final : public IsolateConfiguration {
 public:
  explicit KernelListIsolateConfiguration(
      std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
          kernel_pieces)
      : kernel_piece_futures_(std::move(kernel_pieces)) {
    if (kernel_piece_futures_.empty()) {
      FML_LOG(ERROR) << "Attempted to create kernel list configuration without "
                        "any kernel blobs.";
    }
  }

  // |IsolateConfiguration|
  bool DoPrepareIsolate(DartIsolate& isolate) override {
    if (DartVM::IsRunningPrecompiledCode()) {
      return false;
    }

    ResolveKernelPiecesIfNecessary();

    if (resolved_kernel_pieces_.empty()) {
      FML_DLOG(ERROR) << "No kernel pieces provided to prepare this isolate.";
      return false;
    }

    for (size_t i = 0; i < resolved_kernel_pieces_.size(); i++) {
      if (!resolved_kernel_pieces_[i]) {
        FML_DLOG(ERROR) << "This kernel list isolate configuration was already "
                           "used to prepare an isolate.";
        return false;
      }
      const bool last_piece = i + 1 == resolved_kernel_pieces_.size();
      if (!isolate.PrepareForRunningFromKernel(
              std::move(resolved_kernel_pieces_[i]), /*child_isolate=*/false,
              last_piece)) {
        return false;
      }
    }

    return true;
  }

  // |IsolateConfiguration|
  bool IsNullSafetyEnabled(const DartSnapshot& snapshot) override {
    ResolveKernelPiecesIfNecessary();
    const auto kernel = resolved_kernel_pieces_.empty()
                            ? nullptr
                            : resolved_kernel_pieces_.front().get();
    return snapshot.IsNullSafetyEnabled(kernel);
  }

  // This must be call as late as possible before accessing any of the kernel
  // pieces. This will delay blocking on the futures for as long as possible. So
  // far, only Fuchsia depends on this optimization and only on the non-AOT
  // configs.
  void ResolveKernelPiecesIfNecessary() {
    if (resolved_kernel_pieces_.size() == kernel_piece_futures_.size()) {
      return;
    }

    resolved_kernel_pieces_.clear();
    for (auto& piece : kernel_piece_futures_) {
      // The get() call will xfer the unique pointer out and leave an empty
      // future in the original vector.
      resolved_kernel_pieces_.emplace_back(piece.get());
    }
  }

 private:
  std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
      kernel_piece_futures_;
  std::vector<std::unique_ptr<const fml::Mapping>> resolved_kernel_pieces_;

  FML_DISALLOW_COPY_AND_ASSIGN(KernelListIsolateConfiguration);
};

static std::vector<std::string> ParseKernelListPaths(
    std::unique_ptr<fml::Mapping> kernel_list) {
  FML_DCHECK(kernel_list);

  std::vector<std::string> kernel_pieces_paths;

  const char* kernel_list_str =
      reinterpret_cast<const char*>(kernel_list->GetMapping());
  size_t kernel_list_size = kernel_list->GetSize();

  size_t piece_path_start = 0;
  while (piece_path_start < kernel_list_size) {
    size_t piece_path_end = piece_path_start;
    while ((piece_path_end < kernel_list_size) &&
           (kernel_list_str[piece_path_end] != '\n')) {
      piece_path_end++;
    }
    std::string piece_path(&kernel_list_str[piece_path_start],
                           piece_path_end - piece_path_start);
    kernel_pieces_paths.emplace_back(std::move(piece_path));

    piece_path_start = piece_path_end + 1;
  }

  return kernel_pieces_paths;
}

static std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
PrepareKernelMappings(std::vector<std::string> kernel_pieces_paths,
                      std::shared_ptr<AssetManager> asset_manager,
                      fml::RefPtr<fml::TaskRunner> io_worker) {
  FML_DCHECK(asset_manager);
  std::vector<std::future<std::unique_ptr<const fml::Mapping>>> fetch_futures;

  for (const auto& kernel_pieces_path : kernel_pieces_paths) {
    std::promise<std::unique_ptr<const fml::Mapping>> fetch_promise;
    fetch_futures.push_back(fetch_promise.get_future());
    auto fetch_task =
        fml::MakeCopyable([asset_manager, kernel_pieces_path,
                           fetch_promise = std::move(fetch_promise)]() mutable {
          fetch_promise.set_value(
              asset_manager->GetAsMapping(kernel_pieces_path));
        });
    // Fulfill the promise on the worker if one is available or the current
    // thread if one is not.
    if (io_worker) {
      io_worker->PostTask(fetch_task);
    } else {
      fetch_task();
    }
  }

  return fetch_futures;
}

std::unique_ptr<IsolateConfiguration> IsolateConfiguration::InferFromSettings(
    const Settings& settings,
    std::shared_ptr<AssetManager> asset_manager,
    fml::RefPtr<fml::TaskRunner> io_worker) {
  // Running in AOT mode.
  if (DartVM::IsRunningPrecompiledCode()) {
    return CreateForAppSnapshot();
  }

  if (settings.application_kernels) {
    return CreateForKernelList(settings.application_kernels());
  }

  if (settings.application_kernel_asset.empty() &&
      settings.application_kernel_list_asset.empty()) {
    FML_DLOG(ERROR) << "application_kernel_asset or "
                       "application_kernel_list_asset must be set";
    return nullptr;
  }

  if (!asset_manager) {
    FML_DLOG(ERROR) << "No asset manager specified when attempting to create "
                       "isolate configuration.";
    return nullptr;
  }

  // Running from kernel snapshot. Requires asset manager.
  {
    std::unique_ptr<fml::Mapping> kernel =
        asset_manager->GetAsMapping(settings.application_kernel_asset);
    if (kernel) {
      return CreateForKernel(std::move(kernel));
    }
  }

  // Running from kernel divided into several pieces (for sharing). Requires
  // asset manager and io worker.

  if (!io_worker) {
    FML_DLOG(ERROR) << "No IO worker specified to load kernel pieces.";
    return nullptr;
  }

  {
    std::unique_ptr<fml::Mapping> kernel_list =
        asset_manager->GetAsMapping(settings.application_kernel_list_asset);
    if (!kernel_list) {
      FML_LOG(ERROR) << "Failed to load: "
                     << settings.application_kernel_list_asset;
      return nullptr;
    }
    auto kernel_pieces_paths = ParseKernelListPaths(std::move(kernel_list));
    auto kernel_mappings = PrepareKernelMappings(std::move(kernel_pieces_paths),
                                                 asset_manager, io_worker);
    return CreateForKernelList(std::move(kernel_mappings));
  }

  return nullptr;
}

std::unique_ptr<IsolateConfiguration>
IsolateConfiguration::CreateForAppSnapshot() {
  return std::make_unique<AppSnapshotIsolateConfiguration>();
}

std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernel(
    std::unique_ptr<const fml::Mapping> kernel) {
  return std::make_unique<KernelIsolateConfiguration>(std::move(kernel));
}

std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
    std::vector<std::unique_ptr<const fml::Mapping>> kernel_pieces) {
  std::vector<std::future<std::unique_ptr<const fml::Mapping>>> pieces;
  for (auto& piece : kernel_pieces) {
    if (!piece) {
      FML_DLOG(ERROR) << "Invalid kernel piece.";
      continue;
    }
    std::promise<std::unique_ptr<const fml::Mapping>> promise;
    pieces.push_back(promise.get_future());
    promise.set_value(std::move(piece));
  }
  return CreateForKernelList(std::move(pieces));
}

std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
    std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
        kernel_pieces) {
  return std::make_unique<KernelListIsolateConfiguration>(
      std::move(kernel_pieces));
}

}  // namespace flutter
