// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/directory.h"
#include "include/dart_api.h"
#include "platform/assert.h"
#include "vm/unit_test.h"

namespace dart {

VM_UNIT_TEST_CASE(DirectoryCurrentNoScope) {
  char* current_dir = dart::bin::Directory::CurrentNoScope();
  EXPECT_NOTNULL(current_dir);
  free(current_dir);
}

TEST_CASE(DirectoryCurrent) {
  const char* current = dart::bin::Directory::Current(nullptr);
  EXPECT_NOTNULL(current);
}

TEST_CASE(DirectoryExists) {
  const char* current = dart::bin::Directory::Current(nullptr);
  EXPECT_NOTNULL(current);

  dart::bin::Directory::ExistsResult r =
      dart::bin::Directory::Exists(nullptr, current);
  EXPECT_EQ(dart::bin::Directory::EXISTS, r);
}

TEST_CASE(DirectorySystemTemp) {
  const char* system_temp = dart::bin::Directory::SystemTemp(nullptr);
  EXPECT_NOTNULL(system_temp);
}

TEST_CASE(DirectorySystemTempExists) {
  const char* system_temp = dart::bin::Directory::SystemTemp(nullptr);
  EXPECT_NOTNULL(system_temp);

  dart::bin::Directory::ExistsResult r =
      dart::bin::Directory::Exists(nullptr, system_temp);
  EXPECT_EQ(dart::bin::Directory::EXISTS, r);
}

TEST_CASE(DirectoryCreateTemp) {
  const char* kTempPrefix = "test_prefix";
  const char* system_temp = dart::bin::Directory::SystemTemp(nullptr);
  EXPECT_NOTNULL(system_temp);

  const char* temp_dir = dart::bin::Directory::CreateTemp(nullptr, kTempPrefix);
  EXPECT_NOTNULL(temp_dir);

  // Make sure temp_dir contains test_prefix.
  EXPECT_NOTNULL(strstr(temp_dir, kTempPrefix));

  // Cleanup.
  EXPECT(dart::bin::Directory::Delete(nullptr, temp_dir, false));
}

TEST_CASE(DirectorySetCurrent) {
  const char* current = dart::bin::Directory::Current(nullptr);
  EXPECT_NOTNULL(current);

  const char* system_temp = dart::bin::Directory::SystemTemp(nullptr);
  EXPECT_NOTNULL(system_temp);

  EXPECT(dart::bin::Directory::SetCurrent(nullptr, system_temp));

  const char* new_current = dart::bin::Directory::Current(nullptr);
  EXPECT_NOTNULL(new_current);

  EXPECT_NOTNULL(strstr(new_current, system_temp));

  EXPECT(dart::bin::Directory::SetCurrent(nullptr, current));
}

TEST_CASE(DirectoryCreateDelete) {
  const char* kTempDirName = "create_delete_test_name";

  const char* system_temp = dart::bin::Directory::SystemTemp(nullptr);
  EXPECT_NOTNULL(system_temp);

  const intptr_t name_len =
      snprintf(nullptr, 0, "%s/%s", system_temp, kTempDirName);
  ASSERT(name_len > 0);
  char* name = new char[name_len + 1];
  snprintf(name, name_len + 1, "%s/%s", system_temp, kTempDirName);

  // Make a directory.
  EXPECT(dart::bin::Directory::Create(nullptr, name));

  // Make sure it exists.
  dart::bin::Directory::ExistsResult r =
      dart::bin::Directory::Exists(nullptr, name);
  EXPECT_EQ(dart::bin::Directory::EXISTS, r);

  // Cleanup.
  EXPECT(dart::bin::Directory::Delete(nullptr, name, false));
  delete[] name;
}

TEST_CASE(DirectoryRename) {
  const char* kTempDirName = "rename_test_name";

  const char* system_temp = dart::bin::Directory::SystemTemp(nullptr);
  EXPECT_NOTNULL(system_temp);

  const intptr_t name_len =
      snprintf(nullptr, 0, "%s/%s", system_temp, kTempDirName);
  ASSERT(name_len > 0);
  char* name = new char[name_len + 1];
  snprintf(name, name_len + 1, "%s/%s", system_temp, kTempDirName);

  // Make a directory.
  EXPECT(dart::bin::Directory::Create(nullptr, name));

  // Make sure it exists.
  dart::bin::Directory::ExistsResult r =
      dart::bin::Directory::Exists(nullptr, name);
  EXPECT_EQ(dart::bin::Directory::EXISTS, r);

  const intptr_t new_name_len =
      snprintf(nullptr, 0, "%s/%snewname", system_temp, kTempDirName);
  ASSERT(new_name_len > 0);
  char* new_name = new char[new_name_len + 1];
  snprintf(new_name, new_name_len + 1, "%s/%snewname", system_temp,
           kTempDirName);

  EXPECT(dart::bin::Directory::Rename(nullptr, name, new_name));

  r = dart::bin::Directory::Exists(nullptr, new_name);
  EXPECT_EQ(dart::bin::Directory::EXISTS, r);

  r = dart::bin::Directory::Exists(nullptr, name);
  EXPECT_EQ(dart::bin::Directory::DOES_NOT_EXIST, r);

  EXPECT(dart::bin::Directory::Delete(nullptr, new_name, false));
  delete[] name;
  delete[] new_name;
}

}  // namespace dart
