/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "util/Files.h"

#include <dirent.h>
#include <sys/stat.h>

#include <algorithm>
#include <cerrno>
#include <cstdio>
#include <string>

#include "android-base/errors.h"
#include "android-base/file.h"
#include "android-base/logging.h"
#include "android-base/unique_fd.h"
#include "android-base/utf8.h"

#include "util/Util.h"

#ifdef _WIN32
// Windows includes.
#include <windows.h>
#endif

using ::android::FileMap;
using ::android::StringPiece;
using ::android::base::ReadFileToString;
using ::android::base::SystemErrorCodeToString;
using ::android::base::unique_fd;

namespace aapt {
namespace file {

#ifdef _WIN32
FileType GetFileType(const std::string& path) {
  std::wstring path_utf16;
  if (!::android::base::UTF8PathToWindowsLongPath(path.c_str(), &path_utf16)) {
    return FileType::kNonExistant;
  }

  DWORD result = GetFileAttributesW(path_utf16.c_str());
  if (result == INVALID_FILE_ATTRIBUTES) {
    return FileType::kNonExistant;
  }

  if (result & FILE_ATTRIBUTE_DIRECTORY) {
    return FileType::kDirectory;
  }

  // Too many types to consider, just let open fail later.
  return FileType::kRegular;
}
#else
FileType GetFileType(const std::string& path) {
  struct stat sb;
  int result = stat(path.c_str(), &sb);

  if (result == -1) {
    if (errno == ENOENT || errno == ENOTDIR) {
      return FileType::kNonExistant;
    }
    return FileType::kUnknown;
  }

  if (S_ISREG(sb.st_mode)) {
    return FileType::kRegular;
  } else if (S_ISDIR(sb.st_mode)) {
    return FileType::kDirectory;
  } else if (S_ISCHR(sb.st_mode)) {
    return FileType::kCharDev;
  } else if (S_ISBLK(sb.st_mode)) {
    return FileType::kBlockDev;
  } else if (S_ISFIFO(sb.st_mode)) {
    return FileType::kFifo;
#if defined(S_ISLNK)
  } else if (S_ISLNK(sb.st_mode)) {
    return FileType::kSymlink;
#endif
#if defined(S_ISSOCK)
  } else if (S_ISSOCK(sb.st_mode)) {
    return FileType::kSocket;
#endif
  } else {
    return FileType::kUnknown;
  }
}
#endif

bool mkdirs(const std::string& path) {
 #ifdef _WIN32
  // Start after the long path prefix if present.
  bool require_drive = false;
  size_t current_pos = 0u;
  if (util::StartsWith(path, R"(\\?\)")) {
    require_drive = true;
    current_pos = 4u;
  }

  // Start after the drive path if present.
  if (path.size() >= 3 && path[current_pos + 1] == ':' &&
       (path[current_pos + 2] == '\\' || path[current_pos + 2] == '/')) {
    current_pos += 3u;
  } else if (require_drive) {
    return false;
  }
 #else
  // Start after the first character so that we don't consume the root '/'.
  // This is safe to do with unicode because '/' will never match with a continuation character.
  size_t current_pos = 1u;
 #endif
  constexpr const mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP;
  while ((current_pos = path.find(sDirSep, current_pos)) != std::string::npos) {
    std::string parent_path = path.substr(0, current_pos);
    if (parent_path.empty()) {
      continue;
    }

    int result = ::android::base::utf8::mkdir(parent_path.c_str(), mode);
    if (result < 0 && errno != EEXIST) {
      return false;
    }
    current_pos += 1;
  }
  return ::android::base::utf8::mkdir(path.c_str(), mode) == 0 || errno == EEXIST;
}

StringPiece GetStem(StringPiece path) {
  const char* start = path.begin();
  const char* end = path.end();
  for (const char* current = end - 1; current != start - 1; --current) {
    if (*current == sDirSep) {
      return StringPiece(start, current - start);
    }
  }
  return {};
}

StringPiece GetFilename(StringPiece path) {
  const char* end = path.end();
  const char* last_dir_sep = path.begin();
  for (const char* c = path.begin(); c != end; ++c) {
    if (*c == sDirSep || *c == sInvariantDirSep) {
      last_dir_sep = c + 1;
    }
  }
  return StringPiece(last_dir_sep, end - last_dir_sep);
}

StringPiece GetExtension(StringPiece path) {
  StringPiece filename = GetFilename(path);
  const char* const end = filename.end();
  const char* c = std::find(filename.begin(), end, '.');
  if (c != end) {
    return StringPiece(c, end - c);
  }
  return {};
}

bool IsHidden(android::StringPiece path) {
  return util::StartsWith(GetFilename(path), ".");
}

void AppendPath(std::string* base, StringPiece part) {
  CHECK(base != nullptr);
  const bool base_has_trailing_sep = (!base->empty() && *(base->end() - 1) == sDirSep);
  const bool part_has_leading_sep = (!part.empty() && *(part.begin()) == sDirSep);
  if (base_has_trailing_sep && part_has_leading_sep) {
    // Remove the part's leading sep
    part = part.substr(1, part.size() - 1);
  } else if (!base_has_trailing_sep && !part_has_leading_sep) {
    // None of the pieces has a separator.
    *base += sDirSep;
  }
  base->append(part.data(), part.size());
}

std::string BuildPath(std::vector<const StringPiece>&& args) {
  if (args.empty()) {
    return "";
  }
  std::string out{args[0]};
  for (int i = 1; i < args.size(); i++) {
    file::AppendPath(&out, args[i]);
  }
  return out;
}

std::string PackageToPath(StringPiece package) {
  std::string out_path;
  for (StringPiece part : util::Tokenize(package, '.')) {
    AppendPath(&out_path, part);
  }
  return out_path;
}

std::optional<FileMap> MmapPath(const std::string& path, std::string* out_error) {
  int flags = O_RDONLY | O_CLOEXEC | O_BINARY;
  unique_fd fd(TEMP_FAILURE_RETRY(::android::base::utf8::open(path.c_str(), flags)));
  if (fd == -1) {
    if (out_error) {
      *out_error = SystemErrorCodeToString(errno);
    }
    return {};
  }

  struct stat filestats = {};
  if (fstat(fd, &filestats) != 0) {
    if (out_error) {
      *out_error = SystemErrorCodeToString(errno);
    }
    return {};
  }

  FileMap filemap;
  if (filestats.st_size == 0) {
    // mmap doesn't like a length of 0. Instead we return an empty FileMap.
    return std::move(filemap);
  }

  if (!filemap.create(path.c_str(), fd, 0, filestats.st_size, true)) {
    if (out_error) {
      *out_error = SystemErrorCodeToString(errno);
    }
    return {};
  }
  return std::move(filemap);
}

bool AppendArgsFromFile(StringPiece path, std::vector<std::string>* out_arglist,
                        std::string* out_error) {
  std::string contents;
  if (!ReadFileToString(std::string(path), &contents, true /*follow_symlinks*/)) {
    if (out_error) {
      *out_error = "failed to read argument-list file";
    }
    return false;
  }

  for (StringPiece line : util::Tokenize(contents, ' ')) {
    line = util::TrimWhitespace(line);
    if (!line.empty()) {
      out_arglist->emplace_back(line);
    }
  }
  return true;
}

bool AppendSetArgsFromFile(StringPiece path, std::unordered_set<std::string>* out_argset,
                           std::string* out_error) {
  std::string contents;
  if (!ReadFileToString(std::string(path), &contents, true /*follow_symlinks*/)) {
    if (out_error) {
      *out_error = "failed to read argument-list file";
    }
    return false;
  }

  for (StringPiece line : util::Tokenize(contents, ' ')) {
    line = util::TrimWhitespace(line);
    if (!line.empty()) {
      out_argset->emplace(line);
    }
  }
  return true;
}

bool FileFilter::SetPattern(StringPiece pattern) {
  pattern_tokens_ = util::SplitAndLowercase(pattern, ':');
  return true;
}

bool FileFilter::operator()(const std::string& filename, FileType type) const {
  if (filename == "." || filename == "..") {
    return false;
  }

  const char kDir[] = "dir";
  const char kFile[] = "file";
  const size_t filename_len = filename.length();
  bool chatty = true;
  for (const std::string& token : pattern_tokens_) {
    const char* token_str = token.c_str();
    if (*token_str == '!') {
      chatty = false;
      token_str++;
    }

    if (strncasecmp(token_str, kDir, sizeof(kDir)) == 0) {
      if (type != FileType::kDirectory) {
        continue;
      }
      token_str += sizeof(kDir);
    }

    if (strncasecmp(token_str, kFile, sizeof(kFile)) == 0) {
      if (type != FileType::kRegular) {
        continue;
      }
      token_str += sizeof(kFile);
    }

    bool ignore = false;
    size_t n = strlen(token_str);
    if (*token_str == '*') {
      // Math suffix.
      token_str++;
      n--;
      if (n <= filename_len) {
        ignore =
            strncasecmp(token_str, filename.c_str() + filename_len - n, n) == 0;
      }
    } else if (n > 1 && token_str[n - 1] == '*') {
      // Match prefix.
      ignore = strncasecmp(token_str, filename.c_str(), n - 1) == 0;
    } else {
      ignore = strcasecmp(token_str, filename.c_str()) == 0;
    }

    if (ignore) {
      if (chatty) {
        diag_->Warn(android::DiagMessage()
                    << "skipping " << (type == FileType::kDirectory ? "dir '" : "file '")
                    << filename << "' due to ignore pattern '" << token << "'");
      }
      return false;
    }
  }
  return true;
}

std::optional<std::vector<std::string>> FindFiles(android::StringPiece path,
                                                  android::IDiagnostics* diag,
                                                  const FileFilter* filter) {
  const auto& root_dir = path;
  std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()), closedir);
  if (!d) {
    diag->Error(android::DiagMessage() << SystemErrorCodeToString(errno) << ": " << root_dir);
    return {};
  }

  std::vector<std::string> files;
  std::vector<std::string> subdirs;
  while (struct dirent* entry = readdir(d.get())) {
    if (util::StartsWith(entry->d_name, ".")) {
      continue;
    }

    std::string file_name = entry->d_name;
    std::string full_path{root_dir};
    AppendPath(&full_path, file_name);
    const FileType file_type = GetFileType(full_path);

    if (filter != nullptr) {
      if (!(*filter)(file_name, file_type)) {
        continue;
      }
    }

    if (file_type == file::FileType::kDirectory) {
      subdirs.push_back(std::move(file_name));
    } else {
      files.push_back(std::move(file_name));
    }
  }

  // Now process subdirs.
  for (const std::string& subdir : subdirs) {
    std::string full_subdir{root_dir};
    AppendPath(&full_subdir, subdir);
    std::optional<std::vector<std::string>> subfiles = FindFiles(full_subdir, diag, filter);
    if (!subfiles) {
      return {};
    }

    for (const std::string& subfile : subfiles.value()) {
      std::string new_file = subdir;
      AppendPath(&new_file, subfile);
      files.push_back(new_file);
    }
  }
  return files;
}

}  // namespace file
}  // namespace aapt
