/**
    Read RAW file

    Generate metadata, preview, and thumbnails for EkosLive Offline Viewer.

    2020 Jasem Mutlaq
    Ikarus Technologies
**/

#include "raw.h"

#include <libraw/libraw.h>

#include <QJsonDocument>
#include <QJsonObject>
#include <QFileInfo>
#include <QRegularExpression>
#include <QDateTime>
#include <QUuid>

namespace RAW
{

QByteArray metadata(const QString &filename)
{
    QJsonObject meta;
    // Creation of image processing object
    LibRaw RawProcessor;

    if (RawProcessor.open_file(filename.toLatin1().data()) != LIBRAW_SUCCESS)
    {
        RawProcessor.recycle();
        return QJsonDocument(meta).toJson(QJsonDocument::Compact);
    }

    libraw_data_t *raw = &(RawProcessor.imgdata);

    meta.insert("naxis1", raw->sizes.width);
    meta.insert("naxis2", raw->sizes.height);

    RawProcessor.unpack_thumb();

    meta.insert("naxis", 2);
    meta.insert("bitpix", 16);
    meta.insert("bscale", 1);
    meta.insert("bzero", 32768);
    QString isoTS = QDateTime::fromSecsSinceEpoch(raw->other.timestamp).toString(Qt::ISODate);
    if (isoTS.isEmpty())
        isoTS = QDateTime::currentDateTime().toString(Qt::ISODate);
    meta.insert("date-obs", isoTS);
    meta.insert("xbinning", 1);
    meta.insert("ybinning", 1);
    if (raw->other.shutter > 0)
        meta.insert("exptime", raw->other.shutter);
    if (raw->other.iso_speed > 0)
        meta.insert("ISO", raw->other.iso_speed);

    QString frame = "Light";
    if (filename.contains("Dark/"))
        frame = "Dark";
    else if (filename.contains("Flat/"))
        frame = "Flat";
    else if (filename.contains("Bias/"))
        frame = "Bias";

    meta.insert("frame", frame);

    QString filenameOnly = QFileInfo(filename).fileName();
    int32_t size = QFileInfo(filename).size();
    QString m_UUID = QUuid::createUuid().toString();
    m_UUID = m_UUID.remove(QRegularExpression("[-{}]"));

    // Add filename and size as wells
    meta.insert("uuid", m_UUID);
    meta.insert("filename", filenameOnly);
    meta.insert("filesize", size);
    meta.insert("Content-Disposition", QString("attachment;filename=%1").arg(filenameOnly));


    return QJsonDocument(meta).toJson(QJsonDocument::Compact);
}

QImage toImage(const QString &filename, int maxWidth, int quality)
{
    LibRaw RawProcessor;
    QImage image;

    if (RawProcessor.open_file(filename.toLatin1().data()) != LIBRAW_SUCCESS)
    {
        RawProcessor.recycle();
        return image;
    }

    if (RawProcessor.unpack_thumb() != LIBRAW_SUCCESS)
    {
        RawProcessor.recycle();
        return image;
    }

    int rc = 0;
    libraw_processed_image_t *processed_image = RawProcessor.dcraw_make_mem_thumb(&rc);
    if (rc == LIBRAW_SUCCESS)
    {
        image.loadFromData(reinterpret_cast<uchar *>(processed_image->data), processed_image->data_size);
    }

    RawProcessor.dcraw_clear_mem(processed_image);

    // Resize if necessary
    if (maxWidth > 0 && RawProcessor.imgdata.sizes.width > maxWidth)
        image = image.scaledToWidth(maxWidth, quality > 50 ? Qt::SmoothTransformation : Qt::FastTransformation);

    return image;
}
}
