// 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 "impeller/compiler/includer.h"

#include "flutter/fml/paths.h"

namespace impeller {
namespace compiler {

Includer::Includer(std::shared_ptr<fml::UniqueFD> working_directory,
                   std::vector<IncludeDir> include_dirs,
                   std::function<void(std::string)> on_file_included)
    : working_directory_(std::move(working_directory)),
      include_dirs_(std::move(include_dirs)),
      on_file_included_(std::move(on_file_included)) {}

// |shaderc::CompileOptions::IncluderInterface|
Includer::~Includer() = default;

std::unique_ptr<fml::FileMapping> Includer::TryOpenMapping(
    const IncludeDir& dir,
    const char* requested_source) {
  if (!dir.dir || !dir.dir->is_valid()) {
    return nullptr;
  }

  if (requested_source == nullptr) {
    return nullptr;
  }

  std::string source(requested_source);
  if (source.empty()) {
    return nullptr;
  }

  auto mapping = fml::FileMapping::CreateReadOnly(*dir.dir, requested_source);
  if (!mapping || !mapping->IsValid()) {
    return nullptr;
  }

  on_file_included_(fml::paths::JoinPaths({dir.name, requested_source}));

  return mapping;
}

std::unique_ptr<fml::FileMapping> Includer::FindFirstMapping(
    const char* requested_source) {
  // Always try the working directory first no matter what the include
  // directories are.
  {
    IncludeDir dir;
    dir.name = ".";
    dir.dir = working_directory_;
    if (auto mapping = TryOpenMapping(dir, requested_source)) {
      return mapping;
    }
  }

  for (const auto& include_dir : include_dirs_) {
    if (auto mapping = TryOpenMapping(include_dir, requested_source)) {
      return mapping;
    }
  }
  return nullptr;
}

shaderc_include_result* Includer::GetInclude(const char* requested_source,
                                             shaderc_include_type type,
                                             const char* requesting_source,
                                             size_t include_depth) {
  auto result = std::make_unique<shaderc_include_result>();

  // Default initialize to failed inclusion.
  result->source_name = "";
  result->source_name_length = 0;

  constexpr const char* kFileNotFoundMessage = "Included file not found.";
  result->content = kFileNotFoundMessage;
  result->content_length = ::strlen(kFileNotFoundMessage);
  result->user_data = nullptr;

  if (!working_directory_ || !working_directory_->is_valid()) {
    return result.release();
  }

  if (requested_source == nullptr) {
    return result.release();
  }

  auto file = FindFirstMapping(requested_source);

  if (!file || file->GetMapping() == nullptr) {
    return result.release();
  }

  auto includer_data =
      std::make_unique<IncluderData>(requested_source, std::move(file));

  result->source_name = includer_data->file_name.c_str();
  result->source_name_length = includer_data->file_name.length();
  result->content = reinterpret_cast<decltype(result->content)>(
      includer_data->mapping->GetMapping());
  result->content_length = includer_data->mapping->GetSize();
  result->user_data = includer_data.release();

  return result.release();
}

void Includer::ReleaseInclude(shaderc_include_result* data) {
  delete reinterpret_cast<IncluderData*>(data->user_data);
  delete data;
}

}  // namespace compiler
}  // namespace impeller
