// TestZW.cpp
//------------------------------------------------------------------------------
#if defined( __WINDOWS__ )

// Includes
//------------------------------------------------------------------------------
    #include "FBuildTest.h"

    #include "Core/Strings/AStackString.h"
    #include "Tools/FBuild/FBuildCore/BFF/BFFParser.h"
    #include "Tools/FBuild/FBuildCore/FBuild.h"

//------------------------------------------------------------------------------
TEST_GROUP( TestZW, FBuildTest )
{
public:
};

//------------------------------------------------------------------------------
TEST_CASE( TestZW, Caching )
{
    FBuildTestOptions baseOptions;
    baseOptions.m_ConfigFile = "Tools/FBuild/FBuildTest/Data/TestZW/Caching/fbuild.bff";

    const char * objFile = "../tmp/Test/ZW/Caching/file.obj";
    const char * dbFileName = "../tmp/Test/ZW/Caching/fbuild.fdb";

    // Build, writing to cache
    {
        FBuildOptions options( baseOptions );
        options.m_UseCacheWrite = true;
        options.m_ForceCleanBuild = true;

        FBuildForTest fBuild( options );
        TEST_ASSERT( fBuild.Initialize() );

        EnsureFileDoesNotExist( objFile );

        TEST_ASSERT( fBuild.Build( "Caching" ) );
        TEST_ASSERT( fBuild.SaveDependencyGraph( dbFileName ) );

        EnsureFileExists( objFile );

        // Check we wrote to the cache
        const FBuildStats & stats = fBuild.GetStats();
        CheckStatsNode( stats, 1, 1, Node::OBJECT_NODE );
        TEST_ASSERT( stats.GetCacheStores() == 1 );
    }

    // No op
    {
        FBuildForTest fBuild( baseOptions );
        TEST_ASSERT( fBuild.Initialize( dbFileName ) );
        TEST_ASSERT( fBuild.Build( "Caching" ) );

        // Ensure nothing was built
        const FBuildStats & stats = fBuild.GetStats();
        CheckStatsNode( stats, 1, 0, Node::OBJECT_NODE );
        TEST_ASSERT( stats.GetCacheStores() == 0 );
        TEST_ASSERT( stats.GetCacheHits() == 0 );
    }

    EnsureFileDoesNotExist( objFile );

    // Read from cache
    {
        FBuildOptions options( baseOptions );
        options.m_UseCacheRead = true;

        FBuildForTest fBuild( options );
        TEST_ASSERT( fBuild.Initialize() );
        TEST_ASSERT( fBuild.Build( "Caching" ) );
        TEST_ASSERT( fBuild.SaveDependencyGraph( dbFileName ) );

        EnsureFileExists( objFile );

        // Ensure retrieval from cache
        const FBuildStats & stats = fBuild.GetStats();
        CheckStatsNode( stats, 1, 0, Node::OBJECT_NODE );
        TEST_ASSERT( stats.GetCacheStores() == 0 );
        TEST_ASSERT( stats.GetCacheHits() == 1 );
    }

    // No op (after cache retrieval)
    {
        FBuildForTest fBuild( baseOptions );
        TEST_ASSERT( fBuild.Initialize( dbFileName ) );
        TEST_ASSERT( fBuild.Build( "Caching" ) );

        // Ensure nothing was built
        const FBuildStats & stats = fBuild.GetStats();
        CheckStatsNode( stats, 1, 0, Node::OBJECT_NODE );
        TEST_ASSERT( stats.GetCacheStores() == 0 );
        TEST_ASSERT( stats.GetCacheHits() == 0 );
    }
}

//------------------------------------------------------------------------------
#endif
