// Copyright (C) 2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.

// { dg-options "-DUSE_FILESYSTEM_TS -lstdc++fs" }
// { dg-do run { target c++11 } }
// { dg-require-filesystem-ts "" }

#include <experimental/filesystem>
#include <testsuite_hooks.h>
#include <testsuite_fs.h>

namespace fs = std::experimental::filesystem;

void
test01()
{
  std::error_code ec;
  const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);

  auto p1 = __gnu_test::nonexistent_path();
  auto p2 = __gnu_test::nonexistent_path();

  fs::rename(p1, p2, ec);
  VERIFY( ec );

  ec.clear();
  fs::rename(p1, "", ec);
  VERIFY( ec );

  ec.clear();
  fs::rename("", p1, ec);
  VERIFY( ec );

  ec = bad_ec;
  std::ofstream{p1}; // create file
  fs::rename(p1, p1, ec); // no-op
  VERIFY( !ec );
  VERIFY( is_regular_file(p1) );

  ec.clear();
  rename(p2, p1, ec);
  VERIFY( ec );
  VERIFY( is_regular_file(p1) );

  ec = bad_ec;
  fs::rename(p1, p2, ec);
  VERIFY( !ec );
  VERIFY( !exists(p1) );
  VERIFY( is_regular_file(p2) );

  ec = bad_ec;
  std::ofstream{p1}; // create file
  fs::rename(p1, p2, ec);
  VERIFY( !ec );
  VERIFY( !exists(p1) );
  VERIFY( is_regular_file(p2) );

  fs::remove(p2, ec);
}

void
test_symlinks()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
  // No symlink support
#else
  std::error_code ec;
  const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);

  const auto dir = __gnu_test::nonexistent_path();
  fs::create_directory(dir);

  create_symlink(dir/"nonesuch", dir/"link");  // dangling symlink
  ec = bad_ec;
  fs::rename(dir/"link", dir/"newlink", ec);
  VERIFY( !ec );
  VERIFY( !exists(symlink_status(dir/"link")) );
  VERIFY( is_symlink(dir/"newlink") );

  __gnu_test::scoped_file f(dir/"file");
  create_symlink(dir/"file", dir/"link");
  ec = bad_ec;
  fs::rename(dir/"link", dir/"newerlink", ec);
  VERIFY( !ec );
  VERIFY( !exists(symlink_status(dir/"link")) );
  VERIFY( is_symlink(dir/"newerlink") );
  VERIFY( is_regular_file(dir/"file") );

  fs::remove_all(dir, ec);
  f.path.clear();
#endif
}

void
test_directories()
{
  std::error_code ec;
  const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);

  const auto dir = __gnu_test::nonexistent_path();
  fs::create_directory(dir);
  __gnu_test::scoped_file f(dir/"file");
  fs::create_directory(dir/"subdir");

  // Rename directory.
  ec = bad_ec;
  fs::rename(dir/"subdir", dir/"subdir2", ec);
  VERIFY( !ec );
  VERIFY( is_directory(dir/"subdir2") );
  VERIFY( !exists(dir/"subdir") );

  // Cannot rename a directory to a sub-directory of itself.
  fs::rename(dir/"subdir2", dir/"subdir2/subsubdir", ec);
  VERIFY( ec );
  VERIFY( is_directory(dir/"subdir2") );
  VERIFY( !exists(dir/"subdir2"/"subsubdir") );

  // Cannot rename a file to the name of an existing directory.
  ec.clear();
  fs::rename(dir/"file", dir/"subdir2", ec);
  VERIFY( ec );
  VERIFY( is_directory(dir/"subdir2") );
  VERIFY( is_regular_file(dir/"file") );

#if defined(__MINGW32__) || defined(__MINGW64__)
  // XXX broken on Windows, see PR 98985
#else
  // Cannot rename a directory to the name of an existing non-directory
  ec.clear();
  fs::rename(dir/"subdir2", dir/"file", ec);
  VERIFY( ec );
  VERIFY( is_regular_file(dir/"file") );
  VERIFY( is_directory(dir/"subdir2") );

  // Cannot rename directory to the name of a non-empty directory.
  ec.clear();
  __gnu_test::scoped_file f2(dir/"subdir2/file");
  fs::create_directory(dir/"subdir");
  fs::rename(dir/"subdir", dir/"subdir2", ec);
  VERIFY( ec );
  VERIFY( is_directory(dir/"subdir") );
  VERIFY( is_directory(dir/"subdir2") );
  VERIFY( is_regular_file(dir/"subdir2/file") );

  // Can rename a non-empty directory to the name of an empty directory.
  ec = bad_ec;
  fs::rename(dir/"subdir2", dir/"subdir", ec);
  VERIFY( !ec );
  VERIFY( is_directory(dir/"subdir") );
  VERIFY( !exists(dir/"subdir2") );
  VERIFY( is_regular_file(dir/"subdir/file") );
  f2.path.clear();

  f.path.clear();
#endif

  fs::remove_all(dir, ec);
}

int
main()
{
  test01();
  test_symlinks();
  test_directories();
}
