/*
 * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
 *
 * Distributable under the terms of either the Apache License (Version 2.0) or 
 * the GNU Lesser General Public License, as specified in the COPYING file.
 *
 * Changes are Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
*/
#include <QtCore/QDir>
#include <QtCore/QDateTime>
#include <QtCore/QFileInfo>
#include <QtCore/QByteArray>
#include <QtCore/QCryptographicHash>

#include "CLucene/StdHeader.h"
#include "FSDirectory.h"
#include "CLucene/index/IndexReader.h"
#include "CLucene/util/Misc.h"
#include "CLucene/debug/condition.h"

CL_NS_DEF(store)
CL_NS_USE(util)

bool FSDirectory::disableLocks = false;

// This cache of directories ensures that there is a unique Directory instance
// per path, so that synchronization on the Directory can be used to synchronize
// access between readers and writers.
static CL_NS(util)::CLHashMap<QString, FSDirectory*,
    CL_NS(util)::Compare::Qstring, CL_NS(util)::Equals::Qstring,
    CL_NS(util)::Deletor::DummyQString> DIRECTORIES(false, false);
 
// # pragma mark -- FSDirectory::FSLock

FSDirectory::FSLock::FSLock(const QString& _lockDir, const QString& name)
    : lockDir(_lockDir)
    , lockFile(_lockDir + QDir::separator() + name)
{
}

FSDirectory::FSLock::~FSLock()
{
}

bool FSDirectory::FSLock::obtain()
{
    if (disableLocks)
        return true;

    if (QFile::exists(lockFile))
        return false;

    QDir dir(lockDir);
    if (!dir.exists()) {
        if (!dir.mkpath(lockDir)) {
            // 34: len of "Couldn't create lock directory: "
            char* err = _CL_NEWARRAY(
                char, 34 + strlen(lockDir.toLocal8Bit().constData()) + 1);
            strcpy(err, "Couldn't create lock directory: ");
            strcat(err, lockDir.toLocal8Bit().constData());
            _CLTHROWA_DEL(CL_ERR_IO, err);
        }
    }

    QFile file(lockFile);
    return file.open(QIODevice::ReadWrite);
}

void FSDirectory::FSLock::release()
{
    if (disableLocks)
        return;
    
    QFile file(lockFile);
    file.remove();
}

bool FSDirectory::FSLock::isLocked()
{
    if (disableLocks)
        return false;
    return QFile::exists(lockFile);
}

QString FSDirectory::FSLock::toString() const
{
    QString ret(QLatin1String("Lock@"));
    return ret.append(lockFile);
}

// # pragma mark -- FSDirectory::FSIndexInput

FSDirectory::FSIndexInput::FSIndexInput(const QString& path, int32_t bufferSize)
    : BufferedIndexInput(bufferSize)
{
    CND_PRECONDITION(!path.isEmpty(), "path is NULL");

    handle = _CLNEW SharedHandle();
    handle->fhandle.setFileName(path);
    handle->fhandle.open(QIODevice::ReadOnly);
    
    if (handle->fhandle.error() != QFile::NoError) {
        switch(handle->fhandle.error()) {
            case 1:
                _CLTHROWA(CL_ERR_IO, "An error occurred when reading from the file");
                break;
            case 2:
                _CLTHROWA(CL_ERR_IO, "An error occurred when writing to the file.");
                break;
            case 5:
                _CLTHROWA(CL_ERR_IO, "The file could not be opened.");
                break;
            case 6:
                _CLTHROWA(CL_ERR_IO, "The operation was aborted.");
                break;
            case 7:
                _CLTHROWA(CL_ERR_IO, "A timeout occurred.");
                break;
            case 8:
                _CLTHROWA(CL_ERR_IO, "An unspecified error occurred.");
                break;
            case 9:
                _CLTHROWA(CL_ERR_IO, "The file could not be removed.");
                break;
            case 10:
                _CLTHROWA(CL_ERR_IO, "The file could not be renamed.");
                break;
            case 11:
                _CLTHROWA(CL_ERR_IO, "The position in the file could not be changed.");
                break;
            case 12:
                _CLTHROWA(CL_ERR_IO, "The file could not be resized.e");
                break;
            case 13:
                _CLTHROWA(CL_ERR_IO, "The file could not be accessed.");
                break;
            case 14:
                _CLTHROWA(CL_ERR_IO, "The file could not be copied.");
                break;
            case 4:
            default:
                _CLTHROWA(CL_ERR_IO, "A fatal error occurred.");
        }
    }

    //Store the file length
    handle->_length = handle->fhandle.size();
    handle->_fpos = 0;
    this->_pos = 0;
}

FSDirectory::FSIndexInput::FSIndexInput(const FSIndexInput& other)
    : BufferedIndexInput(other)
{
    if (other.handle == NULL)
        _CLTHROWA(CL_ERR_NullPointer, "other handle is null");

    SCOPED_LOCK_MUTEX(*other.handle->THIS_LOCK)

    _pos = other.handle->_fpos;
    handle = _CL_POINTER(other.handle);
}

FSDirectory::FSIndexInput::~FSIndexInput()
{
    FSIndexInput::close();
}

void FSDirectory::FSIndexInput::close()
{
    BufferedIndexInput::close();
#ifdef _LUCENE_THREADMUTEX
    if (handle != NULL) {
        // Here we have a bit of a problem... We need to lock the handle to
        // ensure that we can safely delete the handle... But if we delete the
        // handle, then the scoped unlock, won't be able to unlock the mutex...

        // take a reference of the lock object...
        _LUCENE_THREADMUTEX* mutex = handle->THIS_LOCK;
        //lock the mutex
        mutex->lock();

        // determine if we are about to delete the handle...
        bool doUnlock = (handle->__cl_refcount > 1);
        // decdelete (deletes if refcount is down to 0)
        _CLDECDELETE(handle);

        if (doUnlock)
            mutex->unlock();
        else
            delete mutex;
    }
#else
    _CLDECDELETE(handle);
#endif
}

IndexInput* FSDirectory::FSIndexInput::clone() const
{
    return _CLNEW FSDirectory::FSIndexInput(*this);
}

void FSDirectory::FSIndexInput::seekInternal(const int64_t position)
{
    CND_PRECONDITION(position >= 0 && position < handle->_length,
        "Seeking out of range")
    _pos = position;
}

void FSDirectory::FSIndexInput::readInternal(uint8_t* b, const int32_t len)
{
    SCOPED_LOCK_MUTEX(*handle->THIS_LOCK)

    CND_PRECONDITION(handle != NULL, "shared file handle has closed");
    CND_PRECONDITION(handle->fhandle.isOpen(), "file is not open");

    if (handle->_fpos != _pos) {
        handle->fhandle.seek(_pos);
        if (handle->fhandle.pos() != _pos)
            _CLTHROWA( CL_ERR_IO, "File IO Seek error");
        handle->_fpos = _pos;
    }

    bufferLength = (int32_t)handle->fhandle.read((char*)b, len);
    if (bufferLength == 0)
        _CLTHROWA(CL_ERR_IO, "read past EOF");

    if (bufferLength == -1)
        _CLTHROWA(CL_ERR_IO, "read error");

    _pos += bufferLength;
    handle->_fpos =_pos;
}

// # pragma mark -- FSDirectory::FSIndexInput::SharedHandle

FSDirectory::FSIndexInput::SharedHandle::SharedHandle()
    : _fpos(0)
    , _length(0)
{
#ifdef _LUCENE_THREADMUTEX
    THIS_LOCK = new _LUCENE_THREADMUTEX;
#endif
}

FSDirectory::FSIndexInput::SharedHandle::~SharedHandle()
{
    if (fhandle.isOpen())
        fhandle.close();
}

// # pragma mark -- FSDirectory::FSIndexOutput

FSDirectory::FSIndexOutput::FSIndexOutput(const QString& path)
{
    //O_BINARY - Opens file in binary (untranslated) mode
    //O_CREAT - Creates and opens new file for writing. Has no effect if file specified by filename exists
    //O_RANDOM - Specifies that caching is optimized for, but not restricted to, random access from disk.
    //O_WRONLY - Opens file for writing only;
    fhandle.setFileName(path);
    fhandle.open(QIODevice::ReadWrite | QIODevice::Truncate);
    
    if (fhandle.error() != QFile::NoError) {
        switch(fhandle.error()) {
            case 1:
                _CLTHROWA(CL_ERR_IO, "An error occurred when reading from the file");
                break;
            case 2:
                _CLTHROWA(CL_ERR_IO, "An error occurred when writing to the file.");
                break;
            case 5:
                _CLTHROWA(CL_ERR_IO, "The file could not be opened.");
                break;
            case 6:
                _CLTHROWA(CL_ERR_IO, "The operation was aborted.");
                break;
            case 7:
                _CLTHROWA(CL_ERR_IO, "A timeout occurred.");
                break;
            case 8:
                _CLTHROWA(CL_ERR_IO, "An unspecified error occurred.");
                break;
            case 9:
                _CLTHROWA(CL_ERR_IO, "The file could not be removed.");
                break;
            case 10:
                _CLTHROWA(CL_ERR_IO, "The file could not be renamed.");
                break;
            case 11:
                _CLTHROWA(CL_ERR_IO, "The position in the file could not be changed.");
                break;
            case 12:
                _CLTHROWA(CL_ERR_IO, "The file could not be resized.e");
                break;
            case 13:
                _CLTHROWA(CL_ERR_IO, "The file could not be accessed.");
                break;
            case 14:
                _CLTHROWA(CL_ERR_IO, "The file could not be copied.");
                break;
            case 4:
            default:
                _CLTHROWA(CL_ERR_IO, "A fatal error occurred.");
        }
    }
}

FSDirectory::FSIndexOutput::~FSIndexOutput()
{
    if (fhandle.isOpen()) {
        try {
            FSIndexOutput::close();
        } catch (CLuceneError& err) {
            //ignore IO errors...
            if (err.number() != CL_ERR_IO)
                throw;
        }
    }
}

void FSDirectory::FSIndexOutput::close()
{
    try {
        BufferedIndexOutput::close();
    } catch (CLuceneError& err) {
        //ignore IO errors...
        if (err.number() != CL_ERR_IO)
            throw;
    }
    fhandle.close();
}

int64_t FSDirectory::FSIndexOutput::length()
{
    CND_PRECONDITION(fhandle.isOpen(), "file is not open");
    return fhandle.size();
}

void FSDirectory::FSIndexOutput::seek(const int64_t pos)
{
    CND_PRECONDITION(fhandle.isOpen(), "file is not open");
    
    BufferedIndexOutput::seek(pos);
    fhandle.seek(pos);
    if (fhandle.pos() != pos)
        _CLTHROWA(CL_ERR_IO, "File IO Seek error");
}

void FSDirectory::FSIndexOutput::flushBuffer(const uint8_t* b, const int32_t size)
{
    CND_PRECONDITION(fhandle.isOpen(), "file is not open");

    if (size > 0 && fhandle.write((const char*)b, size) != size)
        _CLTHROWA(CL_ERR_IO, "File IO Write error");
}

// # pragma mark -- FSDirectory

FSDirectory::FSDirectory(const QString& path, const bool createDir)
    : Directory()
    , refCount(0)
    , useMMap(false)
{
    //set a realpath so that if we change directory, we can still function
    directory = QFileInfo(path).absoluteFilePath();
    lockDir = directory;

    QDir dir(lockDir);
    if (!dir.exists()) {
        if (!dir.mkpath(lockDir))
            _CLTHROWA_DEL(CL_ERR_IO, "Cannot create temp directory");
    }

    QFileInfo info(lockDir);
    if (info.isFile() || info.isSymLink())
        _CLTHROWA(CL_ERR_IO, "Found regular file where directory expected");

    if (createDir)
        create();

    dir.setPath(directory);
    if (!dir.exists()) {
         //19: len of " is not a directory"
        char* err = 
            _CL_NEWARRAY(char, 19 + strlen(path.toLocal8Bit().constData()) + 1);
        strcpy(err, path.toLocal8Bit().constData());
        strcat(err, " is not a directory");
        _CLTHROWA_DEL(CL_ERR_IO, err);
    }
}

void FSDirectory::create()
{
    SCOPED_LOCK_MUTEX(THIS_LOCK)

    bool clear = false;
    QDir dir(directory);
    if (!dir.exists()) {
        if (!dir.mkpath(directory)) {
            char* err = _CL_NEWARRAY( // 27 len of "Couldn't create directory:"
                char, 27 + strlen(directory.toLocal8Bit().constData()) + 1);
            strcpy(err, "Couldn't create directory: ");
            strcat(err, directory.toLocal8Bit().constData());
            _CLTHROWA_DEL(CL_ERR_IO, err);
        }
    } else {
        clear = true;
    }

    QFileInfo info(directory);
    if (info.isFile() || info.isSymLink()) {
        char tmp[1024];
        _snprintf(tmp, 1024, "%s not a directory",
            directory.toLocal8Bit().constData());
        _CLTHROWA(CL_ERR_IO, tmp);
    }

    if (clear) {
        dir.setPath(directory);
        // clear probably existing lucene index files 
        QStringList fileList = dir.entryList(QDir::Files | QDir::Hidden
            | QDir::NoSymLinks);
        foreach(const QString file, fileList) {
            if (CL_NS(index)::IndexReader::isLuceneFile(file)) {
                if (!dir.remove(file))
                    _CLTHROWA(CL_ERR_IO, "Couldn't delete file ");
            }
        }

        // clear probably existing file locks
        QFileInfo dirInfo(lockDir);
        if (dirInfo.exists() && dirInfo.isReadable() && dirInfo.isWritable()
            && !dirInfo.isFile() && !dirInfo.isSymLink()) {
            QDir lockDirectory(lockDir);
            fileList = dir.entryList(QStringList() << getLockPrefix()
                + QLatin1Char('*'), QDir::Files | QDir::Hidden | QDir::NoSymLinks);

            foreach(const QString file, fileList) {
                if (!lockDirectory.remove(file))
                    _CLTHROWA(CL_ERR_IO, "Couldn't delete file ");
            }
        }
        else {
             //todo: richer error: + lockDir.getAbsolutePath());
            _CLTHROWA(CL_ERR_IO, "Cannot read lock directory");
        }
    }
}

void FSDirectory::priv_getFN(QString& buffer, const QString& name) const
{
    buffer.clear();
    buffer.append(directory);
    buffer.append(QDir::separator());
    buffer.append(name);
}

FSDirectory::~FSDirectory()
{
}

QStringList FSDirectory::list() const
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

    QDir dir(directory);
    return dir.entryList(QDir::Files | QDir::Hidden);
}

bool FSDirectory::fileExists(const QString& name) const
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

    QDir dir(directory);
    return dir.entryList().contains(name);
}

QString FSDirectory::getDirName() const
{
    return directory;
}

//static
FSDirectory* FSDirectory::getDirectory(const QString& file, const bool _create)
{
    FSDirectory* dir = NULL;
    {
        if (file.isEmpty())
            _CLTHROWA(CL_ERR_IO, "Invalid directory");

        SCOPED_LOCK_MUTEX(DIRECTORIES.THIS_LOCK)
            dir = DIRECTORIES.get(file);
        if ( dir == NULL  ){
            dir = _CLNEW FSDirectory(file, _create);
            DIRECTORIES.put(dir->directory, dir);
        } else if (_create) {
            dir->create();
        }

        {
            SCOPED_LOCK_MUTEX(dir->THIS_LOCK)
            dir->refCount++;
        }
    }    

    return _CL_POINTER(dir);
}

int64_t FSDirectory::fileModified(const QString& name) const
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

    QFileInfo fInfo(directory + QDir::separator() + name);
    return fInfo.lastModified().toTime_t();
}

//static
int64_t FSDirectory::fileModified(const QString& dir, const QString& name)
{
    QFileInfo fInfo(dir + QDir::separator() + name);
    return fInfo.lastModified().toTime_t();
}

void FSDirectory::touchFile(const QString& name)
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

    QFile file(directory + QDir::separator() + name);
    if (!file.open(QIODevice::ReadWrite))
        _CLTHROWA(CL_ERR_IO, "IO Error while touching file");
}

int64_t FSDirectory::fileLength(const QString& name) const
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

    QFileInfo fInfo(directory + QDir::separator() + name);
    return fInfo.size();
}

IndexInput* FSDirectory::openInput(const QString& name)
{
    return openInput(name, CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE);
}

IndexInput* FSDirectory::openInput(const QString& name, int32_t bufferSize )
{
    CND_PRECONDITION(directory[0]!=0,"directory is not open")

    return _CLNEW FSIndexInput(directory + QDir::separator() + name, bufferSize);
}

void FSDirectory::close()
{
    SCOPED_LOCK_MUTEX(DIRECTORIES.THIS_LOCK)
    {
        SCOPED_LOCK_MUTEX(THIS_LOCK)

        CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

        //refcount starts at 1
        if (--refCount <= 0) {
            Directory* dir = DIRECTORIES.get(getDirName());
            if (dir) {
                //this will be removed in ~FSDirectory
                DIRECTORIES.remove(getDirName());
                _CLDECDELETE(dir);
            }
        }
    }
}

QString FSDirectory::getLockPrefix() const
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

    QString dirName(QFileInfo(directory).absoluteFilePath());
    if (dirName.isEmpty())
        _CLTHROWA(CL_ERR_Runtime, "Invalid directory path");

    // to be compatible with jlucene,
    // we need to make some changes ...
    if (dirName.at(1) == QLatin1Char(':'))
        dirName[0] = dirName.at(0).toUpper();

    TCHAR tBuffer[2048] = { 0 };
    dirName.toWCharArray(tBuffer);
    
    char aBuffer[4096] = { 0 };
    STRCPY_TtoA(aBuffer, tBuffer, 4096);

    QString string(QLatin1String("lucene-"));
    QByteArray hash(QCryptographicHash::hash(aBuffer, QCryptographicHash::Md5));

    // TODO: verify this !!!
    return string.append(QLatin1String(hash.toHex().constData()));
}

bool FSDirectory::doDeleteFile(const QString& name)
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

    QDir dir(directory);
    return dir.remove(name);
}

void FSDirectory::renameFile(const QString& from, const QString& to)
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");
    SCOPED_LOCK_MUTEX(THIS_LOCK)
    
    if (fileExists(to))
        deleteFile(to, false);

    QFile file(directory + QDir::separator() + from);
    QString newFile(directory + QDir::separator() + to);
    if (!file.rename(newFile)) {
        // try a second time if we fail
        if (fileExists(to))
            deleteFile(to, false);

        if (!file.rename(newFile)) {
            QString error(QLatin1String("Could not rename: %1 to %2!!!!"));
            error.arg(from).arg(newFile);
            QByteArray bArray(error.toLocal8Bit());
            _CLTHROWA(CL_ERR_IO, bArray.constData());
        }
    }
}

IndexOutput* FSDirectory::createOutput(const QString& name)
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");

    QString file = directory + QDir::separator() + name;
    if (QFileInfo(file).exists()) {
        if (!QFile::remove(file)) {
            QByteArray bArray("Cannot overwrite: ");
            bArray.append(name.toLocal8Bit());
            _CLTHROWA(CL_ERR_IO, bArray.constData());
        }
    }
    return _CLNEW FSIndexOutput(file);
}

LuceneLock* FSDirectory::makeLock(const QString& name)
{
    CND_PRECONDITION(!directory.isEmpty(), "directory is not open");


    QString lockFile(getLockPrefix());
    lockFile.append(QLatin1Char('-')).append(name);

    return _CLNEW FSLock(lockDir, lockFile);
}

QString FSDirectory::toString() const
{
    return QString::fromLatin1("FSDirectory@").append(directory);
}

CL_NS_END
