#include <uunit.h>

#include <fstream>
#include <map>
#include <vector>

#include <deps.h>
#include <algorithm>

#include "paths.h"
#include "tmpfile.h"

class DepsTest
	: public uUnit
{
public:
	DepsTest()
	{
		uTEST(DepsTest::parser_test);
	}

	void parser_test()
	{
		using namespace std::string_literals;

		auto test_data = paths::top_srcdir / "test" / "deps_test_data";

		auto empty =  test_data / "empty.d";
		auto trivial = test_data / "trivial.d";
		auto no_newline = test_data / "no_newline.d";
		auto no_deps = test_data / "no_deps.d";
		auto trailing_whitespace = test_data / "trailing_whitespace.d";
		auto spaces = test_data / "spaces.d";
		auto multiline = test_data / "multiline.d";
		auto no_such_file = test_data / "no_such_file.d"; // doesn't exist
		auto missing_colon = test_data / "missing_colon.d";

		{
			auto res = readDeps(empty.string(), ctor::toolchain::gcc);
			uASSERT(res.empty());
		}

		{
			auto res = readDeps(trivial.string(), ctor::toolchain::gcc);
			uASSERT_EQUAL(1u, res.size());
			uASSERT_EQUAL("x.cc"s, res[0]);
		}

		{
			auto res = readDeps(no_newline.string(), ctor::toolchain::gcc);
			uASSERT_EQUAL(1u, res.size());
			uASSERT_EQUAL("x.cc"s, res[0]);
		}

		{
			auto res = readDeps(no_deps.string(), ctor::toolchain::gcc);
			uASSERT_EQUAL(0u, res.size());
		}

		{
			auto res = readDeps(spaces.string(), ctor::toolchain::gcc);
			uASSERT_EQUAL(2u, res.size());
			uASSERT_EQUAL("x y.cc"s, res[0]);
			uASSERT_EQUAL("x y.h"s, res[1]);
		}

		{
			auto res = readDeps(multiline.string(), ctor::toolchain::gcc);
			uASSERT_EQUAL(12u, res.size());
			uASSERT_EQUAL("src/configure.cc"s, res[0]);
			uASSERT_EQUAL("src/configure.h"s, res[1]);
			uASSERT_EQUAL("src/getoptpp/getoptpp.hpp"s, res[2]);
			uASSERT_EQUAL("src/execute.h"s, res[3]);
			uASSERT_EQUAL("src/ctor.h"s, res[4]);
			uASSERT_EQUAL("src/tasks.h"s, res[5]);
			uASSERT_EQUAL("src/task.h"s, res[6]);
			uASSERT_EQUAL("src/rebuild.h"s, res[7]);
			uASSERT_EQUAL("src/externals.h"s, res[8]);
			uASSERT_EQUAL("src/externals_manual.h"s, res[9]);
			uASSERT_EQUAL("src/tools.h"s, res[10]);
			uASSERT_EQUAL("src/util.h"s, res[11]);
		}

		{
			auto res = readDeps(no_such_file.string(), ctor::toolchain::gcc);
			uASSERT(res.empty());
		}

		{
			auto res = readDeps(missing_colon.string(), ctor::toolchain::gcc);
			uASSERT(res.empty());
		}
	}
};

// Registers the fixture into the 'registry'
static DepsTest test;