// Copyright 2018 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 "src/lib/files/glob.h"

#include <fcntl.h>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/scoped_temp_dir.h"
#include "src/lib/fxl/strings/substitute.h"

namespace files {
namespace {

class TestGlob : public testing::Test {
 protected:
  TestGlob() {
    // Test directory structure:
    // a
    // aa
    // b
    // c
    // d
    // e
    // subdir/
    //   abcd
    // z

    std::vector<std::string> names = {"a", "b", "c", "d", "z", "e", "aa"};
    for (const auto& name : names) {
      FXL_CHECK(WriteFile(fxl::Substitute("$0/$1", dir_.path(), name), "a", 1));
    }
    FXL_CHECK(CreateDirectory(fxl::Substitute("$0/subdir", dir_.path())));
    FXL_CHECK(WriteFile(fxl::Substitute("$0/subdir/abcd", dir_.path()), "a", 1));
  }

  std::vector<std::string> PrependPath(const std::vector<std::string>& files) {
    std::vector<std::string> ret;
    for (const auto& file : files) {
      ret.push_back(fxl::Substitute("$0/$1", dir_.path(), file));
    }
    return ret;
  }

  ScopedTempDir dir_;
  const std::vector<std::string> sorted_names_in_dir_ = {"a", "aa", "b",      "c",
                                                         "d", "e",  "subdir", "z"};
};  // namespace

TEST_F(TestGlob, Empty) {
  Glob glob({});

  EXPECT_EQ(glob.size(), 0u);
  EXPECT_EQ(glob.begin(), glob.end());
}

TEST_F(TestGlob, EmptyDir) {
  ScopedTempDir dir2;
  auto path = fxl::Substitute("$0/*", dir2.path());
  Glob glob(path);

  EXPECT_EQ(glob.size(), 0u);
  EXPECT_EQ(glob.begin(), glob.end());
}

TEST_F(TestGlob, AllFiles) {
  auto path = fxl::Substitute("$0/*", dir_.path());
  Glob glob(path);
  EXPECT_EQ(glob.size(), sorted_names_in_dir_.size());
  std::vector<std::string> globbed = {glob.begin(), glob.end()};
  EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(sorted_names_in_dir_)));
};

TEST_F(TestGlob, FilePrefix) {
  // Only "a*" files.
  auto path = fxl::Substitute("$0/a*", dir_.path());
  Glob glob(path);
  EXPECT_EQ(glob.size(), 2u);
  std::vector<std::string> globbed = {glob.begin(), glob.end()};
  std::vector<std::string> expected{"a", "aa"};

  EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(expected)));
}

TEST_F(TestGlob, Subdirectory) {
  auto path = fxl::Substitute("$0/*/*", dir_.path());
  Glob glob(path);
  EXPECT_EQ(glob.size(), 1u);
  std::vector<std::string> globbed = {glob.begin(), glob.end()};
  std::vector<std::string> expected{"subdir/abcd"};

  EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(expected)));
}

TEST_F(TestGlob, MultiplePaths) {
  auto path = fxl::Substitute("$0/*", dir_.path());
  auto path2 = fxl::Substitute("$0/*/*", dir_.path());
  Glob glob({path, path2});
  EXPECT_EQ(glob.size(), sorted_names_in_dir_.size() + 1);
  std::vector<std::string> globbed = {glob.begin(), glob.end()};
  std::vector<std::string> expected = sorted_names_in_dir_;
  expected.push_back("subdir/abcd");
  EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(expected)));
}

TEST_F(TestGlob, MarkOption) {
  // Ensure that '/' is appended to directories only.
  auto path = fxl::Substitute("$0/*", dir_.path());
  Glob glob(path, {.mark = true});
  EXPECT_EQ(glob.size(), sorted_names_in_dir_.size());
  std::vector<std::string> globbed = {glob.begin(), glob.end()};
  auto expected = sorted_names_in_dir_;
  expected[expected.size() - 2] += "/";
  EXPECT_THAT(globbed, ::testing::ElementsAreArray(PrependPath(expected)));
  EXPECT_THAT(globbed[globbed.size() - 2], ::testing::EndsWith("subdir/"));
}

TEST_F(TestGlob, NoSortOption) {
  // Ensure we still retrieved the correct entries.
  auto path = fxl::Substitute("$0/*", dir_.path());
  Glob glob(path, {.no_sort = true});
  std::vector<std::string> globbed = {glob.begin(), glob.end()};
  EXPECT_THAT(globbed, ::testing::UnorderedElementsAreArray(PrependPath(sorted_names_in_dir_)));
}

TEST_F(TestGlob, Iterator) {
  // Ensure we still retrieved the correct entries.
  auto path = fxl::Substitute("$0/*", dir_.path());
  Glob glob(path);
  auto it = glob.begin();
  EXPECT_TRUE(it);
  EXPECT_FALSE(glob.end());

  auto first = *it;
  ++it;
  auto second = *it;
  --it;
  EXPECT_TRUE(it);
  EXPECT_EQ(*it, first);
  ++it;
  EXPECT_TRUE(it);
  EXPECT_EQ(*it, second);
}

}  // namespace
}  // namespace files
