// Copyright 2016 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 "lib/tonic/file_loader/file_loader.h"

#include <iostream>
#include <memory>
#include <utility>

#include "lib/ftl/files/directory.h"
#include "lib/ftl/files/file.h"
#include "lib/ftl/files/path.h"
#include "lib/ftl/files/symlink.h"
#include "lib/ftl/logging.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/parsers/packages_map.h"

namespace tonic {
namespace {

constexpr char kPackageScheme[] = "package:";
constexpr size_t kPackageSchemeLength = sizeof(kPackageScheme) - 1;

constexpr char kFileScheme[] = "file:";
constexpr size_t kFileSchemeLength = sizeof(kFileScheme) - 1;

constexpr char kFileURLPrefix[] = "file://";
constexpr size_t kFileURLPrefixLength = sizeof(kFileURLPrefix) - 1;

constexpr char kDartScheme[] = "dart:";

// Extract the scheme prefix ('package:' or 'file:' from )
std::string ExtractSchemePrefix(std::string url) {
  if (url.find(kPackageScheme) == 0u)
    return kPackageScheme;
  if (url.find(kFileScheme) == 0u)
    return kFileScheme;
  return std::string();
}

// Extract the path from a package: or file: url.
std::string ExtractPath(std::string url) {
  if (url.find(kPackageScheme) == 0u)
    return url.substr(kPackageSchemeLength);
  if (url.find(kFileScheme) == 0u)
    return url.substr(kFileSchemeLength);
  return url;
}

}  // namespace

FileLoader::FileLoader() {}

FileLoader::~FileLoader() {}

bool FileLoader::LoadPackagesMap(const std::string& packages) {
  packages_ = packages;
  dependencies_.insert(packages_);
  std::string packages_source;
  if (!files::ReadFileToString(packages_, &packages_source)) {
    std::cerr << "error: Unable to load .packages file '" << packages_ << "'."
              << std::endl;
    return false;
  }
  packages_map_.reset(new PackagesMap());
  std::string error;
  if (!packages_map_->Parse(packages_source, &error)) {
    std::cerr << "error: Unable to parse .packages file '" << packages_ << "'."
              << std::endl
              << error << std::endl;
    return false;
  }
  return true;
}

Dart_Handle FileLoader::HandleLibraryTag(Dart_LibraryTag tag,
                                         Dart_Handle library,
                                         Dart_Handle url) {
  FTL_DCHECK(Dart_IsNull(library) || Dart_IsLibrary(library));
  FTL_DCHECK(Dart_IsString(url));
  if (tag == Dart_kCanonicalizeUrl)
    return CanonicalizeURL(library, url);
  if (tag == Dart_kImportTag)
    return Import(url);
  if (tag == Dart_kSourceTag)
    return Source(library, url);
  if (tag == Dart_kScriptTag)
    return Script(url);
  return Dart_NewApiError("Unknown library tag.");
}

Dart_Handle FileLoader::CanonicalizeURL(Dart_Handle library, Dart_Handle url) {
  std::string string = StdStringFromDart(url);
  if (string.find(kDartScheme) == 0u)
    return url;
  if (string.find(kPackageScheme) == 0u)
    return url;
  if (string.find(kFileScheme) == 0u)
    return StdStringToDart(string.substr(kFileSchemeLength));

  std::string library_url = StdStringFromDart(Dart_LibraryUrl(library));
  std::string prefix = ExtractSchemePrefix(library_url);
  std::string base_path = ExtractPath(library_url);
  std::string simplified_path =
      files::SimplifyPath(files::GetDirectoryName(base_path) + "/" + string);
  return StdStringToDart(prefix + simplified_path);
}

std::string FileLoader::GetFilePathForURL(std::string url) {
  if (url.find(kPackageScheme) == 0u)
    return GetFilePathForPackageURL(std::move(url));
  if (url.find(kFileScheme) == 0u)
    return GetFilePathForFileURL(std::move(url));
  return url;
}

std::string FileLoader::GetFilePathForPackageURL(std::string url) {
  FTL_DCHECK(url.find(kPackageScheme) == 0u);
  url = url.substr(kPackageSchemeLength);
  size_t slash = url.find('/');
  if (slash == std::string::npos)
    return std::string();
  std::string package = url.substr(0, slash);
  std::string library_path = url.substr(slash + 1);
  std::string package_path = packages_map_->Resolve(package);
  if (package_path.empty())
    return std::string();
  if (package_path.find(kFileURLPrefix) == 0u)
    return package_path.substr(kFileURLPrefixLength) + library_path;
  return files::GetDirectoryName(packages_) + "/" + package_path + "/" +
         library_path;
}

std::string FileLoader::GetFilePathForFileURL(std::string url) {
  FTL_DCHECK(url.find(kFileURLPrefix) == 0u);
  return url.substr(kFileURLPrefixLength);
}

std::string FileLoader::GetFileURLForPath(const std::string& path) {
  return std::string(kFileURLPrefix) + path;
}

std::string FileLoader::Fetch(const std::string& url,
                              std::string* resolved_url) {
  std::string path = GetFilePathForURL(url);
  if (resolved_url)
    *resolved_url = GetFileURLForPath(path);
  std::string source;
  if (!files::ReadFileToString(files::GetAbsoluteFilePath(path), &source)) {
    // TODO(johnmccutchan): The file loader should not explicitly log the error
    // or exit the process. Instead these errors should be reported to the
    // caller of the FileLoader who can implement the application-specific error
    // handling policy.
    FTL_LOG(ERROR) << "error: Unable to read Dart source '" << url << "'.";
    exit(1);
  }
  url_dependencies_.insert(url);
  dependencies_.insert(path);
  return source;
}

Dart_Handle FileLoader::LoadLibrary(const std::string& url) {
  std::string resolved_url;
  Dart_Handle source = ToDart(Fetch(url, &resolved_url));
  return Dart_LoadLibrary(ToDart(url), ToDart(resolved_url), source, 0, 0);
}

Dart_Handle FileLoader::LoadScript(const std::string& url) {
  std::string resolved_url;
  Dart_Handle source = ToDart(Fetch(url, &resolved_url));
  Dart_Handle result =
      Dart_LoadScript(ToDart(url), ToDart(resolved_url), source, 0, 0);
  if (!Dart_IsError(result)) {
    Dart_Handle finalize_result = Dart_FinalizeLoading(true);
    if (Dart_IsError(finalize_result))
      return finalize_result;
  }
  return result;
}

Dart_Handle FileLoader::Import(Dart_Handle url) {
  return LoadLibrary(StdStringFromDart(url));
}

Dart_Handle FileLoader::Source(Dart_Handle library, Dart_Handle url) {
  std::string resolved_url;
  Dart_Handle source = ToDart(Fetch(StdStringFromDart(url), &resolved_url));
  return Dart_LoadSource(library, url, ToDart(resolved_url), source, 0, 0);
}

Dart_Handle FileLoader::Script(Dart_Handle url) {
  return LoadScript(StdStringFromDart(url));
}

}  // namespace tonic
