/*****************************************************************************
 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Test of file functions: ReadFile(), FileSize(), RemoveFile(), etc.
 *//*
 * LEGAL:   COPYRIGHT (C) 2005 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#define TESTING 1
#include <sstream>
#include <fstream>
#include "test.hh"
#include "base/module.hh"
#include "base/file.hh"
using namespace base;

/*****************************************************************************
 * Test.
 *****************************************************************************/
bool
Test( void )
{
    const string fname = "/tmp/test_file.dat";

    // Ensure dummy file doesn't exist yet.
//  if ( ! RemoveFile( fname ) ) return Fail();  // will normally return false
    RemoveFile( fname );  // ensure 
    if ( IfFileExists( fname ) ) return Fail();

    // Create dummy file.
    std::fstream fs;
    fs.open( fname.c_str(), std::ios::out | std::ios::binary | std::ios::trunc );
    if ( ! fs.good() || ! fs.is_open() ) return Fail();
    if ( not IfFileExists( fname ) ) return Fail();

    // Write dummy data to string stream.
    std::ostringstream os;
    for ( int i = 0; i < 100; ++i ) os << "abc123\n";

    // Write to dummy file.
    //fs << os;
    fs << os.str();
    if ( ! fs.good() || ! fs.is_open() ) return Fail();

    // Close dummy file.
    fs.flush();
    fs.close();

    // Read the file.
    string ibuf;
    if ( ! ReadFile( fname, ibuf ) ) return Fail();
    if ( ibuf != os.str() ) return Fail();
    if ( ibuf.size() == 0 || os.str().size() == 0 ) return Fail();

    // Now try error cases (missing file).
    if ( ReadFile( "MISSING_FILE", ibuf ) ) return Fail();
    // Skip FileSize(FILE*) as fopen("MISSING_FILE") would return NULL (core dump).

    // Cleanup.
    if ( ! RemoveFile( fname ) ) return Fail();
    if ( IfFileExists( fname ) ) return Fail();

    return true;
}

/*****************************************************************************
 * Test misc file functions.
 *****************************************************************************/
bool
Test2( void )
{
// RemoveSuffix()
    {
        string fname = "test.txt";
        RemoveSuffix( fname, ".txt" );
        if ( fname != "test" ) return Fail();
    }

    {
        string fname = "test.txt";
        RemoveSuffix( fname, ".MISSING" );  // should be a NOP
        if ( fname != "test.txt" ) return Fail();
    }

// IfPathIsAbsolute()
// [2009/12] These functions support both Windows and UNIX file naming regardless of build.
    {
        const string fname = "test.txt";
        if ( IfPathIsAbsolute(fname) ) return Fail();
    }

    {
        const string fname = "/test.txt";
        if ( not IfPathIsAbsolute(fname) ) return Fail();
    }

    {
        const string fname = "\\test.txt";
        if ( not IfPathIsAbsolute(fname) ) return Fail();
    }

    {
        const string fname = "c:test.txt";
        if ( not IfPathIsAbsolute(fname) ) return Fail();
    }

    {
        const string fname = "c:\\test.txt";
        if ( not IfPathIsAbsolute(fname) ) return Fail();
    }

    {
        const string fname = "Z://test.txt";
        if ( not IfPathIsAbsolute(fname) ) return Fail();
    }

    {
        const string fname = "/";
        if ( not IfPathIsAbsolute(fname) ) return Fail();
    }

    {
        const string fname = "\\";
        if ( not IfPathIsAbsolute(fname) ) return Fail();
    }

    {
        const string fname;  // empty
        if ( IfPathIsAbsolute(fname) ) return Fail();
    }

// IfPathIsFilename()
// [2009/12] These functions support both Windows and UNIX file naming regardless of build.
    {
        const string fname = "test.txt";
        if ( not IfPathIsFilename(fname) ) return Fail();
    }

    {
        const string fname = "test";
        if ( not IfPathIsFilename(fname) ) return Fail();
    }

    {
        const string fname = "a";
        if ( not IfPathIsFilename(fname) ) return Fail();
    }

    {
        const string fname = "/test.txt";
        if ( IfPathIsFilename(fname) ) return Fail();
    }

    {
        const string fname = "test/test.txt";
        if ( IfPathIsFilename(fname) ) return Fail();
    }

    {
        const string fname = "c:test.txt";
        if ( IfPathIsFilename(fname) ) return Fail();
    }

    {
        const string fname = "t";
        if ( not IfPathIsFilename(fname) ) return Fail();
    }

    {
        const string fname;  // empty
        if ( IfPathIsFilename(fname) ) return Fail();
    }

    return true;
}

/*****************************************************************************
 * Test FileBasename().
 *****************************************************************************/
bool
TestFileBasename( void )
{
    {
        const string path = "test.txt";
        const string path2 = FileBasename( path );
        if ( path2 != "test.txt" ) return Fail();
    }

    {
        const string path = "/test.txt";
        const string path2 = FileBasename( path );
        if ( path2 != "test.txt" ) return Fail();
    }

    {
        const string path = "tmp/test.txt";
        const string path2 = FileBasename( path );
        if ( path2 != "test.txt" ) return Fail();
    }

    {
        const string path = "/tmp/tmp/test.txt";
        const string path2 = FileBasename( path );
        if ( path2 != "test.txt" ) return Fail();
    }

    {
        const string path = "/a";
        const string path2 = FileBasename( path );
        if ( path2 != "a" ) return Fail();
    }

    {
        const string path = "\\a";
        const string path2 = FileBasename( path );
        if ( path2 != "a" ) return Fail();
    }

    {
        const string path = "abc/";
        const string path2 = FileBasename( path );
        if ( path2 == "abc" ) return Fail();  // has no basename nor filename
    }

    {
        const string path = "/";
        const string path2 = FileBasename( path );
        // (undefined)
    }

    {
        const string path;
        const string path2 = FileBasename( path );
        // (undefined)
    }

    return true;
}

/*****************************************************************************
 * main.
 *****************************************************************************/
int
main( int argc, char** argv )
{
    RUN_TEST( "file", TEST_ERROR_MODE_ABORT,
              Test()
          and Test2()
          and TestFileBasename() )
}
