#include <catch2/catch.hpp>

#include "regexp/properties/RegExpEpsilon.h"
#include "regexp/properties/RegExpEmpty.h"

#include <factory/StringDataFactory.hpp>
#include <regexp/string/UnboundedRegExp.h>

TEST_CASE ( "RegExp properties", "[unit][algo][regexp][properties]" ) {
	SECTION ( "Describes epsilon" ) {
		{
			std::string input = "#E + ( (a #E) + a*)";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
		}
		{
			std::string input = "( a* )( a* )";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
		}
		{
			std::string input = "a + #0";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
		}
		{
			std::string input = "#E + a #E + a*";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
		}
		{
			std::string input = "a* a*";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
		}
		{
			std::string input = "a s d #E + #E #0";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
		}
		{
			std::string input = "a + #0";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
		}
	}

	SECTION ( "Describes empty language" ) {
		{
			std::string input = "(#E #0 ) + ( #0 a + (b ( #0 (a*) ) ) )";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(regexp::properties::RegExpEmpty::languageIsEmpty(re));
		}
		{
			std::string input = "(#E + a ) + ( #0 a + (b ( #0 (a*) ) ) )";
			regexp::UnboundedRegExp < > re = factory::StringDataFactory::fromString (input);

			CHECK(! regexp::properties::RegExpEmpty::languageIsEmpty(re));
		}
	}
}
