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

#include "flutter/fml/logging.h"
#include "flutter/fml/unique_fd.h"

namespace fml {

static fml::UniqueFD CreateDirectory(const fml::UniqueFD& base_directory,
                                     const std::vector<std::string>& components,
                                     FilePermission permission,
                                     size_t index) {
  FML_DCHECK(index <= components.size());

  const char* file_path = components[index].c_str();

  auto directory = OpenDirectory(base_directory, file_path, true, permission);

  if (!directory.is_valid()) {
    return {};
  }

  if (index == components.size() - 1) {
    return directory;
  }

  return CreateDirectory(directory, components, permission, index + 1);
}

fml::UniqueFD CreateDirectory(const fml::UniqueFD& base_directory,
                              const std::vector<std::string>& components,
                              FilePermission permission) {
  if (!IsDirectory(base_directory)) {
    return {};
  }

  if (components.size() == 0) {
    return {};
  }

  return CreateDirectory(base_directory, components, permission, 0);
}

ScopedTemporaryDirectory::ScopedTemporaryDirectory()
    : path_(CreateTemporaryDirectory()) {
  if (path_ != "") {
    dir_fd_ = OpenDirectory(path_.c_str(), false, FilePermission::kRead);
  }
}

ScopedTemporaryDirectory::~ScopedTemporaryDirectory() {
  // POSIX requires the directory to be empty before UnlinkDirectory.
  if (path_ != "") {
    if (!RemoveFilesInDirectory(dir_fd_)) {
      FML_LOG(ERROR) << "Could not clean directory: " << path_;
    }
  }

  // Windows has to close UniqueFD first before UnlinkDirectory
  dir_fd_.reset();
  if (path_ != "") {
    if (!UnlinkDirectory(path_.c_str())) {
      FML_LOG(ERROR) << "Could not remove directory: " << path_;
    }
  }
}

bool VisitFilesRecursively(const fml::UniqueFD& directory,
                           const FileVisitor& visitor) {
  FileVisitor recursive_visitor = [&recursive_visitor, &visitor](
                                      const UniqueFD& directory,
                                      const std::string& filename) {
    if (!visitor(directory, filename)) {
      return false;
    }
    if (IsDirectory(directory, filename.c_str())) {
      UniqueFD sub_dir = OpenDirectoryReadOnly(directory, filename.c_str());
      if (!sub_dir.is_valid()) {
        FML_LOG(ERROR) << "Can't open sub-directory: " << filename;
        return true;
      }
      return VisitFiles(sub_dir, recursive_visitor);
    }
    return true;
  };
  return VisitFiles(directory, recursive_visitor);
}

fml::UniqueFD OpenFileReadOnly(const fml::UniqueFD& base_directory,
                               const char* path) {
  return OpenFile(base_directory, path, false, FilePermission::kRead);
}

fml::UniqueFD OpenDirectoryReadOnly(const fml::UniqueFD& base_directory,
                                    const char* path) {
  return OpenDirectory(base_directory, path, false, FilePermission::kRead);
}

bool RemoveFilesInDirectory(const fml::UniqueFD& directory) {
  fml::FileVisitor recursive_cleanup = [&recursive_cleanup](
                                           const fml::UniqueFD& directory,
                                           const std::string& filename) {
    bool removed;
    if (fml::IsDirectory(directory, filename.c_str())) {
      fml::UniqueFD sub_dir =
          OpenDirectoryReadOnly(directory, filename.c_str());
      removed = VisitFiles(sub_dir, recursive_cleanup) &&
                fml::UnlinkDirectory(directory, filename.c_str());
    } else {
      removed = fml::UnlinkFile(directory, filename.c_str());
    }
    return removed;
  };
  return VisitFiles(directory, recursive_cleanup);
}

bool RemoveDirectoryRecursively(const fml::UniqueFD& parent,
                                const char* directory_name) {
  auto dir = fml::OpenDirectory(parent, directory_name, false,
                                fml::FilePermission::kReadWrite);
  return RemoveFilesInDirectory(dir) && UnlinkDirectory(parent, directory_name);
}

}  // namespace fml
