#include "Notebook.h"
#include "CellModel.h"
#include "../PPrint.h"

#include <QJsonObject>
#include <QJsonArray>
#include <QFileDialog>
#include <QDebug>

// TODO: avoid potential race condition if Cell is deleted, pass by value with same UUID instead

Notebook::~Notebook()
{
    _rtThread->quit();
    _rtThread->wait();

    delete _rt;
}

Notebook::Notebook(QObject *parent)
    : QObject(parent)
    , _cellModel(new CellModel(this))
    , _rtThread(new QThread(this))
    , _rt(new NbRuntime)
{
    connect(_rt, &NbRuntime::cellFailedToParse, this, &Notebook::cellFailedToParse);
    connect(_rt, &NbRuntime::cellFinishedRunning, this, &Notebook::cellFinishedRunning);
    connect(_rt, &NbRuntime::cellQuit, this, &Notebook::cellQuit);
    connect(_rt, &NbRuntime::cellRunning, this, &Notebook::cellRunning);
    connect(_rt, &NbRuntime::cellWaiting, this, &Notebook::cellWaiting);

    _rt->moveToThread(_rtThread);
    _rtThread->start();
}

Notebook::Notebook(const Notebook &other, QObject *parent)
    : Notebook(parent)
{
    for (const Cell *cell : other._cells)
    {
        _cells.append(new Cell(*cell, this));
    }
}

CellModel *Notebook::cellModel()
{
    return _cellModel;
}

void Notebook::runCell(QUuid uuid)
{
    qInfo() << "Running cell" << uuid;
    _rt->queueCell(Cell::cellFromUuid(uuid));
}

void Notebook::quitCell(QUuid uuid)
{
    _rt->unqueueCell(Cell::cellFromUuid(uuid));
}

void Notebook::fromJson(QJsonDocument doc)
{
    QJsonObject nb = doc.object();
    QJsonArray cellArray = nb["cells"].toArray();

    for (const QJsonValueRef &cell : cellArray)
    {
        cellModel()->insertCellBefore(cellModel()->rowCount());
        _cells.last()->fromJson(cell.toObject());
    }
}

void Notebook::open(QString path)
{
    QFile file(path);

    if (file.exists())
    {
        file.open(QFile::ReadOnly);

        QJsonParseError error;
        QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);

        if (error.error == QJsonParseError::NoError)
        {
            fromJson(doc);
        }
        else
        {
            qWarning() << error.errorString();
        }

        file.close();
        setSavePath(path);
    }
    else
    {
        qWarning() << "File does not exist" << path;
    }
}

QJsonDocument Notebook::toJson() const
{
    QJsonObject nb;
    QJsonArray cellArray;

    for (const Cell *cell : _cells)
    {
        cellArray.append(cell->toJson());
    }

    nb["cells"] = cellArray;

    return QJsonDocument(nb);
}

void Notebook::save()
{
    if (_savePath == "")
    {
        setSavePath(QFileDialog::getSaveFileName(nullptr, "Open Refal Notebook", "", "Refal Notebooks (*.refnb)"));
    }

    QJsonDocument doc = toJson();
    QFile save(_savePath);
    save.open(QFile::WriteOnly);

    if (!save.isOpen())
    {
        emit saveError(save.errorString());
        return;
    }

    save.write(doc.toJson(QJsonDocument::Indented));
    save.close();
}

bool Notebook::savePathSet()
{
    return _savePath != "";
}

QString Notebook::savePath()
{
    return _savePath;
}

void Notebook::setSavePath(QString savePath)
{
    _savePath = savePath;
    emit savePathChanged(savePath);
}

void Notebook::cellFinishedRunning(Cell *cell, RuntimeResult result)
{
    qInfo() << "cellFinishedRunning" << cell->uuid() << pprint(result);
    cell->setResult(pprint(result));
    cell->setStatus(Cell::IDLE);
    cell->setResultType(Cell::EXPRESSION);
}

void Notebook::cellFailedToParse(Cell *cell, ParseResult result, Parser parser)
{
    qInfo() << "cellFailedToParse" << cell->uuid() << pprint(result, parser);
    cell->setResult(pprint(result, parser, PPrint::HTML));
    cell->setStatus(Cell::IDLE);
    cell->setResultType(Cell::DIAGNOSTIC);
}

void Notebook::cellWaiting(Cell *cell)
{
    qInfo() << "cellWaiting" << cell->uuid();
    cell->setStatus(Cell::WAITING);
}

void Notebook::cellRunning(Cell *cell)
{
    qInfo() << "cellRunning" << cell->uuid();
    cell->setStatus(Cell::RUNNING);
}

void Notebook::cellQuit(Cell *cell)
{
    qInfo() << "cellQuit" << cell->uuid();
    cell->setResult("");
    cell->setStatus(Cell::IDLE);
}
