/*
 * Distributed under the Boost Software License, Version 1.0.(See accompanying 
 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
 * 
 * See http://www.boost.org/libs/iostreams for documentation.
 *
 * Tests seeking with a file_descriptor using large file offsets.
 *
 * File:        libs/iostreams/test/large_file_test.cpp
 * Date:        Tue Dec 25 21:34:47 MST 2007
 * Copyright:   2007-2008 CodeRage, LLC
 * Author:      Jonathan Turkanis
 * Contact:     turkanis at coderage dot com
 */

#include <cstdio>            // SEEK_SET, etc.
#include <ctime>
#include <string>
#include <boost/config.hpp>  // BOOST_STRINGIZE
#include <boost/detail/workaround.hpp>
#include <boost/iostreams/detail/config/rtl.hpp>
#include <boost/iostreams/detail/config/windows_posix.hpp>
#include <boost/iostreams/detail/execute.hpp>
#include <boost/iostreams/detail/ios.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/iostreams/positioning.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <iostream>

    // OS-specific headers for low-level i/o.

#include <fcntl.h>       // file opening flags.
#include <sys/stat.h>    // file access permissions.
#ifdef BOOST_IOSTREAMS_WINDOWS
# include <io.h>         // low-level file i/o.
# define WINDOWS_LEAN_AND_MEAN
# include <windows.h>
# ifndef INVALID_SET_FILE_POINTER
#  define INVALID_SET_FILE_POINTER ((DWORD)-1)
# endif
#else
# include <sys/types.h>  // mode_t.
# include <unistd.h>     // low-level file i/o.
#endif  

using namespace std;
using namespace boost;
using namespace boost::iostreams;
using boost::unit_test::test_suite;

//------------------Definition of constants-----------------------------------//

const stream_offset gigabyte = 1073741824;
const stream_offset file_size = // Some compilers complain about "8589934593"
    gigabyte * static_cast<stream_offset>(8) + static_cast<stream_offset>(1);
const int offset_list[] = 
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, // Seek by 1GB
      0, 2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6, 8,       // Seek by 2GB
         6, 7, 5, 6, 4, 5, 3, 4, 2, 3, 1, 2, 
      0, 3, 1, 4, 2, 5, 3, 6, 4, 7, 5, 8,             // Seek by 3GB
         5, 7, 4, 6, 3, 5, 2, 4, 1,
      0, 4, 1, 5, 2, 6, 3, 7, 4, 8,                   // Seek by 4GB
         4, 7, 3, 6, 2, 5, 1, 4,
      0, 5, 1, 6, 2, 7, 3, 8, 3, 7, 2, 6, 1, 5,       // Seek by 5GB
      0, 6, 1, 7, 2, 8, 2, 7, 1, 6,                   // Seek by 6GB
      0, 7, 1, 8, 1, 7,                               // Seek by 7GB
      0, 8, 0 };                                      // Seek by 8GB
const int offset_list_length = sizeof(offset_list) / sizeof(int);
#ifdef LARGE_FILE_TEMP
# define BOOST_FILE_NAME BOOST_STRINGIZE(LARGE_FILE_TEMP)
# define BOOST_KEEP_FILE false
#else
# define BOOST_FILE_NAME BOOST_STRINGIZE(LARGE_FILE_KEEP)
# define BOOST_KEEP_FILE true
#endif

//------------------Definition of remove_large_file---------------------------//

// Removes the large file
void remove_large_file()
{
#ifdef BOOST_IOSTREAMS_WINDOWS
    DeleteFile(TEXT(BOOST_FILE_NAME));
#else
    unlink(BOOST_FILE_NAME);
#endif
}

//------------------Definition of large_file_exists---------------------------//

// Returns true if the large file exists, has the correct size, and has been
// modified since the last commit affecting this source file; if the file exists
// but is invalid, deletes the file.
bool large_file_exists()
{
    // Last mod date
    time_t last_mod;

#ifdef BOOST_IOSTREAMS_WINDOWS

    // Check existence
    WIN32_FIND_DATA info;
    HANDLE hnd = FindFirstFile(TEXT(BOOST_FILE_NAME), &info);
    if (hnd == INVALID_HANDLE_VALUE) 
        return false;

    // Check size
    FindClose(hnd);
    stream_offset size = 
        (static_cast<stream_offset>(info.nFileSizeHigh) << 32) + 
        static_cast<stream_offset>(info.nFileSizeLow);
    if (size != file_size) {
        remove_large_file();
        return false;
    }

    // Fetch last mod date
    SYSTEMTIME stime;
    if (!FileTimeToSystemTime(&info.ftLastWriteTime, &stime)) {
        remove_large_file();
        return false;    
    }
    tm ctime;
    ctime.tm_year = stime.wYear - 1900;
    ctime.tm_mon = stime.wMonth - 1;
    ctime.tm_mday = stime.wDay;
    ctime.tm_hour = stime.wHour;
    ctime.tm_min = stime.wMinute;
    ctime.tm_sec = stime.wSecond;
    ctime.tm_isdst = 0;
    last_mod = mktime(&ctime);

#else

    // Check existence
    struct BOOST_IOSTREAMS_FD_STAT info;
    if (BOOST_IOSTREAMS_FD_STAT(BOOST_FILE_NAME, &info))
        return false;

    // Check size
    if (info.st_size != file_size) {
        remove_large_file();
        return false;
    }

    // Fetch last mod date
    last_mod = info.st_mtime;

#endif

    // Fetch last mod date of this file ("large_file_test.cpp")
    string timestamp = 
        "$Date: 2009-05-20 15:41:20 -0400 (Wed, 20 May 2009) $";
    if (timestamp.size() != 53) { // Length of auto-generated SVN timestamp
        remove_large_file();
        return false;
    }
    tm commit;
    try {
        commit.tm_year = lexical_cast<int>(timestamp.substr(7, 4)) - 1900;
        commit.tm_mon = lexical_cast<int>(timestamp.substr(12, 2)) - 1;
        commit.tm_mday = lexical_cast<int>(timestamp.substr(15, 2));
        commit.tm_hour = lexical_cast<int>(timestamp.substr(18, 2));
        commit.tm_min = lexical_cast<int>(timestamp.substr(21, 2));
        commit.tm_sec = lexical_cast<int>(timestamp.substr(24, 2));
    } catch (const bad_lexical_cast&) {
        remove_large_file();
        return false;
    }

    // If last commit was two days or more before file timestamp, existing 
    // file is okay; otherwise, it must be regenerated (the two-day window 
    // compensates for time zone differences)
    return difftime(last_mod, mktime(&commit)) >= 60 * 60 * 48; 
}

//------------------Definition of map_large_file------------------------------//

// Initializes the large file by mapping it in small segments. This is an
// optimization for Win32; the straightforward implementation using WriteFile 
// and SetFilePointer (see the Borland workaropund below) is painfully slow.
bool map_large_file()
{
    for (stream_offset z = 0; z <= 8; ++z) {
        try {
            mapped_file_params params;
            params.path = BOOST_FILE_NAME;
            params.offset = z * gigabyte;
            params.length = 1;
            params.mode = BOOST_IOS::out;
            mapped_file file(params);
            file.begin()[0] = z + 1;
        } catch (const std::exception&) {
            remove_large_file();
            return false;
        }
    }
    return true;
}

//------------------Definition of create_large_file---------------------------//

// Creates and initializes the large file if it does not already exist. The file 
// looks like this:
//     
//     0     1GB   2GB   3GB   4GB   5GB   6GB   7GB   8GB
//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//     1.....2.....3.....4.....5.....6.....7.....8.....9
//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// where the characters 1-9 appear at offsets that are multiples of 1GB and the
// dots represent uninitialized data.
bool create_large_file()
{
    // If file exists, has correct size, and is recent, we're done
    if (BOOST_KEEP_FILE && large_file_exists())
        return true;

#ifdef BOOST_IOSTREAMS_WINDOWS

    // Create file
    HANDLE hnd =
        CreateFile(
            TEXT(BOOST_FILE_NAME),
            GENERIC_WRITE,
            0,
            NULL,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );
    if (!hnd)
        return false;

    // Set file pointer
    LONG off_low = static_cast<LONG>(file_size & 0xffffffff);
    LONG off_high = static_cast<LONG>(file_size >> 32);
    if ( SetFilePointer(hnd, off_low, &off_high, FILE_BEGIN) == 
            INVALID_SET_FILE_POINTER && 
         GetLastError() != NO_ERROR ) 
    {
        CloseHandle(hnd);
        remove_large_file();
        return false;
    }

    // Set file size
    if (!SetEndOfFile(hnd)) {
        CloseHandle(hnd);
        remove_large_file();
        return false;
    }

# if !defined(__BORLANDC__) || __BORLANDC__ < 0x582 || __BORLANDC__ >= 0x592

    // Close handle; all further access is via mapped_file
    CloseHandle(hnd);

    // Initialize file data
    return map_large_file();

# else // Borland >= 5.8.2 and Borland < 5.9.2

    // Initialize file data (very slow, even though only 9 writes are required)
    for (stream_offset z = 0; z <= 8; ++z) {

        // Seek
        LONG off_low = static_cast<LONG>((z * gigabyte) & 0xffffffff); // == 0
        LONG off_high = static_cast<LONG>((z * gigabyte) >> 32);
        if ( SetFilePointer(hnd, off_low, &off_high, FILE_BEGIN) == 
                INVALID_SET_FILE_POINTER && 
             GetLastError() != NO_ERROR ) 
        {
            CloseHandle(hnd);
            remove_large_file();
            return false;
        }

        // Write a character
        char buf[1] = { z + 1 };
        DWORD result;
        BOOL success = WriteFile(hnd, buf, 1, &result, NULL);
        if (!success || result != 1) {
            CloseHandle(hnd);
            remove_large_file();
            return false;
        }
    }

    // Close file
    CloseHandle(hnd);
    return true;

# endif // Borland workaround
#else // #ifdef BOOST_IOSTREAMS_WINDOWS

    // Create file
    int oflag = O_WRONLY | O_CREAT;
    #ifdef _LARGEFILE64_SOURCE
        oflag |= O_LARGEFILE;
    #endif
    mode_t pmode = 
        S_IRUSR | S_IWUSR |
        S_IRGRP | S_IWGRP |
        S_IROTH | S_IWOTH;
    int fd = BOOST_IOSTREAMS_FD_OPEN(BOOST_FILE_NAME, oflag, pmode);
    if (fd == -1)
        return false;

    // Set file size
    if (BOOST_IOSTREAMS_FD_TRUNCATE(fd, file_size)) {
        BOOST_IOSTREAMS_FD_CLOSE(fd);
        return false;
    }

# ifndef __CYGWIN__

    // Initialize file data
    for (int z = 0; z <= 8; ++z) {

        // Seek
        BOOST_IOSTREAMS_FD_OFFSET off = 
            BOOST_IOSTREAMS_FD_SEEK(
                fd,
                static_cast<BOOST_IOSTREAMS_FD_OFFSET>(z * gigabyte),
                SEEK_SET
            );
        if (off == -1) {
            BOOST_IOSTREAMS_FD_CLOSE(fd);
            return false;
        }

        // Write a character
        char buf[1] = { z + 1 };
        if (BOOST_IOSTREAMS_FD_WRITE(fd, buf, 1) == -1) {
            BOOST_IOSTREAMS_FD_CLOSE(fd);
            return false;
        }
    }

    // Close file
    BOOST_IOSTREAMS_FD_CLOSE(fd);
    return true;

# else // Cygwin

    // Close descriptor; all further access is via mapped_file
    BOOST_IOSTREAMS_FD_CLOSE(fd);

    // Initialize file data
    return map_large_file();

# endif 
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
}

//------------------Definition of large_file----------------------------------//

// RAII utility
class large_file {
public:
    large_file() { exists_ = create_large_file(); }
    ~large_file() { if (!BOOST_KEEP_FILE) remove_large_file(); }
    bool exists() const { return exists_; }
    const char* path() const { return BOOST_FILE_NAME; }
private:
    bool exists_;
};
                    
//------------------Definition of check_character-----------------------------//

// Verify that the given file contains the given character at the current 
// position
bool check_character(file_descriptor_source& file, char value)
{
    char           buf[1];
    int            amt;
    BOOST_CHECK_NO_THROW(amt = file.read(buf, 1));
    BOOST_CHECK_MESSAGE(amt == 1, "failed reading character");
    BOOST_CHECK_NO_THROW(file.seek(-1, BOOST_IOS::cur));
    return buf[0] == value;
}

//------------------Definition of large_file_test-----------------------------//

void large_file_test()
{
    BOOST_REQUIRE_MESSAGE(
        sizeof(stream_offset) >= 8,
        "large offsets not supported"
    );

    // Prepare file and file descriptor
    large_file              large;
    file_descriptor_source  file;
    BOOST_REQUIRE_MESSAGE(
        large.exists(), "failed creating file \"" << BOOST_FILE_NAME << '"'
    );
    BOOST_CHECK_NO_THROW(file.open(large.path(), BOOST_IOS::binary));

    // Test seeking using ios_base::beg
    for (int z = 0; z < offset_list_length; ++z) {
        char value = offset_list[z] + 1;
        stream_offset off = 
            static_cast<stream_offset>(offset_list[z]) * gigabyte;
        BOOST_CHECK_NO_THROW(file.seek(off, BOOST_IOS::beg));
        BOOST_CHECK_MESSAGE(
            check_character(file, value), 
            "failed validating seek"
        );
    }

    // Test seeking using ios_base::end
    for (int z = 0; z < offset_list_length; ++z) {
        char value = offset_list[z] + 1;
        stream_offset off = 
            -static_cast<stream_offset>(8 - offset_list[z]) * gigabyte - 1;
        BOOST_CHECK_NO_THROW(file.seek(off, BOOST_IOS::end));
        BOOST_CHECK_MESSAGE(
            check_character(file, value), 
            "failed validating seek"
        );
    }

    // Test seeking using ios_base::cur
    for (int next, cur = 0, z = 0; z < offset_list_length; ++z, cur = next) {
        next = offset_list[z];
        char value = offset_list[z] + 1;
        stream_offset off = static_cast<stream_offset>(next - cur) * gigabyte;
        BOOST_CHECK_NO_THROW(file.seek(off, BOOST_IOS::cur));
        BOOST_CHECK_MESSAGE(
            check_character(file, value), 
            "failed validating seek"
        );
    }
}

test_suite* init_unit_test_suite(int, char* []) 
{
    test_suite* test = BOOST_TEST_SUITE("execute test");
    test->add(BOOST_TEST_CASE(&large_file_test));
    return test;
}
