/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

#define CUSTOM_EXTENSION_INIT

#include <filesystem>

#include "unit/TestBase.h"
#include "unit/Catch.h"
#include "utils/file/FilePattern.h"
#include "range/v3/view/map.hpp"
#include "range/v3/view/join.hpp"
#include "range/v3/range/conversion.hpp"

using FilePattern = minifi::utils::file::FilePattern;

struct FilePatternTestAccessor {
  using FilePatternSegment = minifi::utils::file::FilePattern::FilePatternSegment;
};

using FilePatternSegment = FilePatternTestAccessor::FilePatternSegment;

#ifdef WIN32
static std::filesystem::path root{"C:\\"};
#else
static std::filesystem::path root{"/"};
#endif

TEST_CASE("Invalid paths") {
  CHECK_THROWS(FilePatternSegment(""));
  CHECK_THROWS(FilePatternSegment("."));
  CHECK_THROWS(FilePatternSegment(".."));
  CHECK_THROWS(FilePatternSegment("!"));
  CHECK_THROWS(FilePatternSegment("!."));
  CHECK_THROWS(FilePatternSegment("!.."));
  // parent accessor after wildcard
  // sanity check
  FilePatternSegment("./../file.txt");  // NOLINT(bugprone-unused-raii)
  CHECK_THROWS(FilePatternSegment("./*/../file.txt"));
}

TEST_CASE("FilePattern reports error in correct subpattern") {
  std::vector<std::pair<std::string_view, std::string_view>> invalid_subpattern{
      {"", "Empty pattern"},
      {".", "Invalid file pattern '.'"},
      {"..", "Invalid file pattern '..'"},
      {"!./*/../file.txt", "Parent accessor is not supported after wildcards"},
      {"./", "Empty file pattern"}
  };
  auto pattern = invalid_subpattern | ranges::views::keys | ranges::views::join(',') | ranges::to<std::string>;
  size_t idx = 0;
  FilePattern(pattern, [&] (std::string_view subpattern, std::string_view error) {  // NOLINT(bugprone-unused-raii)
    CHECK(invalid_subpattern[idx].first == subpattern);
    CHECK(invalid_subpattern[idx++].second == error);
  });
  CHECK(idx == invalid_subpattern.size());
}

TEST_CASE("Matching directories without globs") {
  FilePatternSegment pattern((root / "one" / "banana" / "file").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "two/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "apple/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  // this looks at the DIRECTORY "/one/banana/file", while our pattern
  // looks for the FILE "/one/banana/file"
  CHECK(pattern.match(root / "one" / "banana" / "file/") == FilePatternSegment::MatchResult::NOT_MATCHING);
}

TEST_CASE("Matching directories with double asterisk") {
  FilePatternSegment pattern((root / "one" / "**" / "file").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / "inner/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "two/") == FilePatternSegment::MatchResult::NOT_MATCHING);
}

TEST_CASE("Matching directories with trailing double asterisk") {
  FilePatternSegment pattern((root / "one" / "**").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / "inner/") == FilePatternSegment::MatchResult::INCLUDE);
}

TEST_CASE("Matching directories with single asterisk") {
  FilePatternSegment pattern((root / "one" / "*e*" / "file").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "then/") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "then" / "inner/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "not/") == FilePatternSegment::MatchResult::NOT_MATCHING);
}

TEST_CASE("Matching files without globs") {
  FilePatternSegment pattern((root / "one" / "banana" / "file").string());
  CHECK(pattern.match(root / "one" / "file") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "banana" / "file") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / "not_file") == FilePatternSegment::MatchResult::NOT_MATCHING);
}

TEST_CASE("Matching files with single asterisk") {
  FilePatternSegment pattern((root / "one" / "banana" / "*.txt").string());
  CHECK(pattern.match(root / "one" / "file") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "banana" / "file.txt") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / ".txt") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / "file.jpg") == FilePatternSegment::MatchResult::NOT_MATCHING);
}

TEST_CASE("Matching files with double asterisk in directory") {
  FilePatternSegment pattern((root / "one" / "**" / "banana" / "*.txt").string());
  CHECK(pattern.match(root / "one" / "file.txt") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "banana" / "file.txt") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "inter" / "banana" / "other.txt") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "inter" / "banana" / "not-good" / "other.txt") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "inter" / "inter2" / "banana" / "other.txt") == FilePatternSegment::MatchResult::INCLUDE);
}

TEST_CASE("Matching files with trailing double asterisk") {
  FilePatternSegment pattern((root / "one" / "**").string());
  CHECK(pattern.match(root / "one" / "file.txt") == FilePatternSegment::MatchResult::INCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / "file.txt") == FilePatternSegment::MatchResult::INCLUDE);
}

TEST_CASE("Matching directory with exclusion") {
  TestController controller;
  std::filesystem::path root{controller.createTempDirectory()};
  // root
  //   |- file1.txt
  //   |- one
  //   |   |- file2.txt
  //   |   |- apple
  //   |   |   |- file3.jpg
  //   |   |   |- file4.txt
  //   |   |
  //   |   |- banana
  //   |        |- file5.txt
  //   |- two
  //       |- file6.txt
  minifi::utils::file::create_dir(root / "one" / "apple", true);
  minifi::utils::file::create_dir(root / "one" / "banana", true);
  minifi::utils::file::create_dir(root / "two", true);

  auto file1 = root / "file1.txt";
  auto file2 = root / "one" / "file2.txt";
  auto file3 = root / "one" / "apple" / "file3.jpg";
  auto file4 = root / "one" / "apple" / "file4.txt";
  auto file5 = root / "one" / "banana" / "file5.txt";
  auto file6 = root / "two" / "file6.txt";

  std::set<std::filesystem::path> files{file1, file2, file3, file4, file5, file6};

  for (const auto& file : files) {std::ofstream{file};}

  // match all
  auto matched_files = minifi::utils::file::match(FilePattern((root / "**").string()));
  CHECK(matched_files == files);

  // match txt files
  matched_files = minifi::utils::file::match(FilePattern((root / "**" / "*.txt").string()));
  CHECK((matched_files == std::set<std::filesystem::path>{file1, file2, file4, file5, file6}));

  // match everything in /one, but not in /one/apple
  matched_files = minifi::utils::file::match(FilePattern((root / "one" / "**").string() + ",!" + (root / "one" / "apple" / "**").string()));
  CHECK((matched_files == std::set<std::filesystem::path>{file2, file5}));

  // match everything in /one/banana, and in /two
  matched_files = minifi::utils::file::match(FilePattern((root / "one" / "banana" / "**").string() + "," + (root / "two" / "**").string()));
  CHECK((matched_files == std::set<std::filesystem::path>{file5, file6}));

  // match everything in / not in /one, /two but in /one/apple
  matched_files = minifi::utils::file::match(FilePattern(
      root.string() +
      ",!" + (root / "one" / "**").string() +
      "," + (root / "one" / "apple" / "**").string() +
      ",!" + (root / "two" / "**").string()));
  CHECK((matched_files == std::set<std::filesystem::path>{file3, file4}));

  // exclude a single file
  matched_files = minifi::utils::file::match(FilePattern((root / "one" / "apple" / "**").string() + ",!" + (root / "one" / "apple" / "file3.jpg").string()));
  CHECK((matched_files == std::set<std::filesystem::path>{file4}));

  // exclude by file extension
  matched_files = minifi::utils::file::match(FilePattern((root / "**").string() + ",!" + (root / "**" / "*.txt").string()));
  CHECK((matched_files == std::set<std::filesystem::path>{file3}));

  // exclude files with name "*tx*" (everything except the jpg)
  matched_files = minifi::utils::file::match(FilePattern((root / "**").string() + ",!" + (root / "**" / "*tx*").string()));
  CHECK((matched_files == std::set<std::filesystem::path>{file3}));
}

TEST_CASE("Excluding directories with directory-tree exclusion") {
  FilePatternSegment pattern("!" + (root / "one" / "**").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::EXCLUDE);
  CHECK(pattern.match(root / "one" / "banana/") == FilePatternSegment::MatchResult::EXCLUDE);
  CHECK(pattern.match(root / "two/") == FilePatternSegment::MatchResult::NOT_MATCHING);
}

TEST_CASE("Excluding files with directory-tree exclusion") {
  FilePatternSegment pattern("!" + (root / "one" / "**").string());
  CHECK(pattern.match(root / "one" / "file.txt") == FilePatternSegment::MatchResult::EXCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / "other.txt") == FilePatternSegment::MatchResult::EXCLUDE);
  CHECK(pattern.match(root / "two" / "no-excluded.txt") == FilePatternSegment::MatchResult::NOT_MATCHING);
}

TEST_CASE("Excluding with specific file exclusion") {
  FilePatternSegment pattern("!" + (root / "one" / "banana" / "file.txt").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "file.txt") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "two" / "no-excluded.txt") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "banana" / "other.txt") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "banana" / "file.txt") == FilePatternSegment::MatchResult::EXCLUDE);
}

TEST_CASE("Excluding with file wildcards") {
  FilePatternSegment pattern("!" + (root / "one" / "banana" / "*.txt").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "banana" / "other.txt") == FilePatternSegment::MatchResult::EXCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / "file.txt") == FilePatternSegment::MatchResult::EXCLUDE);
}

TEST_CASE("Excluding with directory-tree file specific exclusion") {
  FilePatternSegment pattern("!" + (root / "one" / "**" / "file.txt").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "file.txt") == FilePatternSegment::MatchResult::EXCLUDE);
  CHECK(pattern.match(root / "one" / "banana" / "file.txt") == FilePatternSegment::MatchResult::EXCLUDE);
}

TEST_CASE("Excluding with directory wildcard exclusion") {
  FilePatternSegment pattern("!" + (root / "one" / "*e*" / "*").string());
  CHECK(pattern.match(root / "one/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  // even though it seems to match, it would exclude the likes of "/one/ten/banana/file.txt"
  CHECK(pattern.match(root / "one" / "ten/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "six/") == FilePatternSegment::MatchResult::NOT_MATCHING);
  CHECK(pattern.match(root / "one" / "ten" / "file.txt") == FilePatternSegment::MatchResult::EXCLUDE);
}

TEST_CASE("Check only relevant subdir contents") {
  TestController controller;
  std::filesystem::path root{controller.createTempDirectory()};
  // root
  //   |- file1.txt
  //   |- one
  //   |   |- file2.txt
  //   |
  //   |- two
  //       |- file3.txt
  minifi::utils::file::create_dir(root / "one", true);
  minifi::utils::file::create_dir(root / "two", true);

  auto file1 = root / "file1.txt";
  auto file2 = root / "one" / "file2.txt";
  auto file3 = root / "two" / "file3.txt";

  for (const auto& file : {file1, file2, file3}) {std::ofstream{file};}

  std::set<std::filesystem::path> checked_files;
  auto file_cb = [&] (const std::filesystem::path& dir, const std::filesystem::path& file) -> bool {
    checked_files.insert(dir / file);
    return true;
  };
  auto dir_cb = [&] (const std::filesystem::path& dir) -> bool {
    // only check the "one" subdir
    return dir == root / "one";
  };
  utils::file::list_dir(root.string(), file_cb, controller.getLogger(), dir_cb);

  CHECK((checked_files == std::set<std::filesystem::path>{file1, file2}));
}
