// Copyright 2011 Google Inc. All Rights Reserved.
//
// 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.

#ifndef NINJA_TEST_H_
#define NINJA_TEST_H_

#include "disk_interface.h"
#include "manifest_parser.h"
#include "state.h"
#include "util.h"

// A tiny testing framework inspired by googletest, but much simpler and
// faster to compile. It supports most things commonly used from googltest. The
// most noticeable things missing: EXPECT_* and ASSERT_* don't support
// streaming notes to them with operator<<, and for failing tests the lhs and
// rhs are not printed. That's so that this header does not have to include
// sstream, which slows down building ninja_test almost 20%.
namespace testing {
class Test {
  bool failed_;
  int assertion_failures_;
 public:
  Test() : failed_(false), assertion_failures_(0) {}
  virtual ~Test() {}
  virtual void SetUp() {}
  virtual void TearDown() {}
  virtual void Run() = 0;

  bool Failed() const { return failed_; }
  int AssertionFailures() const { return assertion_failures_; }
  void AddAssertionFailure() { assertion_failures_++; }
  bool Check(bool condition, const char* file, int line, const char* error);
};
}

void RegisterTest(testing::Test* (*)(), const char*);

extern testing::Test* g_current_test;
#define TEST_F_(x, y, name)                                           \
  struct y : public x {                                               \
    static testing::Test* Create() { return g_current_test = new y; } \
    virtual void Run();                                               \
  };                                                                  \
  struct Register##y {                                                \
    Register##y() { RegisterTest(y::Create, name); }                  \
  };                                                                  \
  Register##y g_register_##y;                                         \
  void y::Run()

#define TEST_F(x, y) TEST_F_(x, x##y, #x "." #y)
#define TEST(x, y) TEST_F_(testing::Test, x##y, #x "." #y)

#define EXPECT_EQ(a, b) \
  g_current_test->Check(a == b, __FILE__, __LINE__, #a " == " #b)
#define EXPECT_NE(a, b) \
  g_current_test->Check(a != b, __FILE__, __LINE__, #a " != " #b)
#define EXPECT_GT(a, b) \
  g_current_test->Check(a > b, __FILE__, __LINE__, #a " > " #b)
#define EXPECT_LT(a, b) \
  g_current_test->Check(a < b, __FILE__, __LINE__, #a " < " #b)
#define EXPECT_GE(a, b) \
  g_current_test->Check(a >= b, __FILE__, __LINE__, #a " >= " #b)
#define EXPECT_LE(a, b) \
  g_current_test->Check(a <= b, __FILE__, __LINE__, #a " <= " #b)
#define EXPECT_TRUE(a) \
  g_current_test->Check(static_cast<bool>(a), __FILE__, __LINE__, #a)
#define EXPECT_FALSE(a) \
  g_current_test->Check(!static_cast<bool>(a), __FILE__, __LINE__, #a)

#define ASSERT_EQ(a, b) \
  if (!EXPECT_EQ(a, b)) { g_current_test->AddAssertionFailure(); return; }
#define ASSERT_NE(a, b) \
  if (!EXPECT_NE(a, b)) { g_current_test->AddAssertionFailure(); return; }
#define ASSERT_GT(a, b) \
  if (!EXPECT_GT(a, b)) { g_current_test->AddAssertionFailure(); return; }
#define ASSERT_LT(a, b) \
  if (!EXPECT_LT(a, b)) { g_current_test->AddAssertionFailure(); return; }
#define ASSERT_GE(a, b) \
  if (!EXPECT_GE(a, b)) { g_current_test->AddAssertionFailure(); return; }
#define ASSERT_LE(a, b) \
  if (!EXPECT_LE(a, b)) { g_current_test->AddAssertionFailure(); return; }
#define ASSERT_TRUE(a)  \
  if (!EXPECT_TRUE(a))  { g_current_test->AddAssertionFailure(); return; }
#define ASSERT_FALSE(a) \
  if (!EXPECT_FALSE(a)) { g_current_test->AddAssertionFailure(); return; }
#define ASSERT_NO_FATAL_FAILURE(a)                           \
  {                                                          \
    int fail_count = g_current_test->AssertionFailures();    \
    a;                                                       \
    if (fail_count != g_current_test->AssertionFailures()) { \
      g_current_test->AddAssertionFailure();                 \
      return;                                                \
    }                                                        \
  }

// Support utilities for tests.

struct Node;

/// A base test fixture that includes a State object with a
/// builtin "cat" rule.
struct StateTestWithBuiltinRules : public testing::Test {
  StateTestWithBuiltinRules();

  /// Add a "cat" rule to \a state.  Used by some tests; it's
  /// otherwise done by the ctor to state_.
  void AddCatRule(State* state);

  /// Short way to get a Node by its path from state_.
  Node* GetNode(const string& path);

  State state_;
};

void AssertParse(State* state, const char* input,
                 ManifestParserOptions = ManifestParserOptions());
void AssertHash(const char* expected, uint64_t actual);
void VerifyGraph(const State& state);

/// An implementation of DiskInterface that uses an in-memory representation
/// of disk state.  It also logs file accesses and directory creations
/// so it can be used by tests to verify disk access patterns.
struct VirtualFileSystem : public DiskInterface {
  VirtualFileSystem() : now_(1) {}

  /// "Create" a file with contents.
  void Create(const string& path, const string& contents);

  /// "Create" a symlink pointing to another path.
  void CreateSymlink(const string& path, const string& dest);

  /// Tick "time" forwards; subsequent file operations will be newer than
  /// previous ones.
  int Tick() {
    return ++now_;
  }

  // DiskInterface
  virtual TimeStamp Stat(const string& path, string* err) const;
  virtual TimeStamp LStat(const string& path, bool* is_dir, bool* is_symlink, string* err) const;
  virtual bool IsStatThreadSafe() const;
  virtual bool WriteFile(const string& path, const string& contents);
  virtual bool MakeDir(const string& path);
  virtual Status ReadFile(const string& path, string* contents, string* err);
  virtual Status LoadFile(const std::string& path,
                          std::unique_ptr<LoadedFile>* result,
                          std::string* err);
  virtual int RemoveFile(const string& path);

  /// An entry for a single in-memory file.
  struct Entry {
    int mtime;
    string stat_error;  // If mtime is -1.
    string contents;
    bool is_symlink = false;
  };
  struct DirEntry {
    int mtime;
    string stat_error;  // If mtime is -1.
  };

  vector<string> directories_made_;
  vector<string> files_read_;
  typedef map<string, DirEntry> DirMap;
  DirMap dirs_;
  typedef map<string, Entry> FileMap;
  FileMap files_;
  set<string> files_removed_;
  set<string> files_created_;

  /// A simple fake timestamp for file operations.
  int now_;
};

struct ScopedTempDir {
  /// Create a temporary directory and chdir into it.
  void CreateAndEnter(const string& name);

  /// Clean up the temporary directory.
  void Cleanup();

  /// The temp directory containing our dir.
  string start_dir_;
  /// The subdirectory name for our dir, or empty if it hasn't been set up.
  string temp_dir_name_;
};

// A C++11 version of operator "" s from C++14's std::string_literals.
inline std::string operator "" _s(const char* str, size_t len) {
  return { str, len };
}

#endif // NINJA_TEST_H_
