#include "fitswrapper.h"
#include <QDebug>
#include <QFile>

FITSWrapper::FITSWrapper(const QString &path, int mode, bool open)
{
    _path = path;
    _mode = mode;

    if(open)
        fits_open_diskfile(&_file, path.toLocal8Bit().data(), mode, &_status);
    else
        fits_create_diskfile(&_file, path.toLocal8Bit().data(), &_status);

    if(_status == FILE_NOT_OPENED || _status == FILE_NOT_CREATED)
    {
        qWarning() << "Could not open file directly trying memfile workaround" << path;
        if(open)
        {
            QFile fr(path);
            if(fr.open(QIODevice::ReadOnly))
            {
                _bufferSize = fr.size();
                _bufferPtr = malloc(_bufferSize);
                fr.read((char*)_bufferPtr, _bufferSize);
                _status = 0;
                fits_open_memfile(&_file, "memfile", mode, &_bufferPtr, &_bufferSize, 0, realloc, &_status);
                if(_status)
                {
                    free(_bufferPtr);
                    _bufferPtr = nullptr;
                    _bufferSize = 0;
                    qWarning() << "fits_open_memfile failed";
                }
            }
            else
            {
                qWarning() << "QFile failed to open file" << path;
                _status = FILE_NOT_OPENED;
            }
        }
        else
        {
            _bufferSize = 2880;
            _bufferPtr = malloc(_bufferSize);
            fits_create_memfile(&_file, &_bufferPtr, &_bufferSize, 0, realloc, &_status);
            if(_status)
            {
                free(_bufferPtr);
                _bufferPtr = nullptr;
                _bufferSize = 0;
            }
        }
    }
}

FITSWrapper::~FITSWrapper()
{
    if(_file)
    {
        _status = 0;
        fits_close_file(_file, &_status);
    }

    if(_mode == READWRITE && _bufferPtr)
    {
        qDebug() << "Writing FITS memfile" << _bufferSize;
        QFile fw(_path);
        if(fw.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            if(fw.write((char*)_bufferPtr, _bufferSize) != (qint64)_bufferSize)
                qWarning() << "Failed to write to file";
        }
        else
            qWarning() << "Failed to open fits file for writing";
    }

    free(_bufferPtr);
}

int FITSWrapper::status() const
{
    return _status;
}

FITSWrapper::operator fitsfile *()
{
    return _file;
}
