/****************************************************************************
**
** Copyright (C) 2017 Denis Shienkov <denis.shienkov@gmail.com>
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtSerialBus module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "tinycanbackend.h"
#include "tinycanbackend_p.h"

#include "tinycan_symbols_p.h"

#include <QtSerialBus/qcanbusdevice.h>

#include <QtCore/qtimer.h>
#include <QtCore/qmutex.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qloggingcategory.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

Q_DECLARE_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_TINYCAN)

#ifndef LINK_LIBMHSTCAN
Q_GLOBAL_STATIC(QLibrary, mhstcanLibrary)
#endif

bool TinyCanBackend::canCreate(QString *errorReason)
{
#ifdef LINK_LIBMHSTCAN
    return true;
#else
    static bool symbolsResolved = resolveTinyCanSymbols(mhstcanLibrary());
    if (Q_UNLIKELY(!symbolsResolved)) {
        *errorReason = mhstcanLibrary()->errorString();
        return false;
    }
    return true;
#endif
}

QList<QCanBusDeviceInfo> TinyCanBackend::interfaces()
{
    QList<QCanBusDeviceInfo> result;
    result.append(createDeviceInfo(QStringLiteral("can0.0")));
    return result;
}

namespace {

struct TinyCanGlobal {
    QList<TinyCanBackendPrivate *> channels;
    QMutex mutex;
};

} // namespace

Q_GLOBAL_STATIC(TinyCanGlobal, gTinyCan)

class TinyCanWriteNotifier : public QTimer
{
    // no Q_OBJECT macro!
public:
    TinyCanWriteNotifier(TinyCanBackendPrivate *d, QObject *parent)
        : QTimer(parent)
        , dptr(d)
    {
    }

protected:
    void timerEvent(QTimerEvent *e) override
    {
        if (e->timerId() == timerId()) {
            dptr->startWrite();
            return;
        }
        QTimer::timerEvent(e);
    }

private:
    TinyCanBackendPrivate * const dptr;
};

static int driverRefCount = 0;

static void DRV_CALLBACK_TYPE canRxEventCallback(quint32 index, TCanMsg *frame, qint32 count)
{
    Q_UNUSED(frame);
    Q_UNUSED(count);

    QMutexLocker lock(&gTinyCan->mutex);
    for (TinyCanBackendPrivate *p : qAsConst(gTinyCan->channels)) {
        if (p->channelIndex == int(index)) {
            p->startRead();
            return;
        }
    }
}

TinyCanBackendPrivate::TinyCanBackendPrivate(TinyCanBackend *q)
    : q_ptr(q)
{
    startupDriver();

    QMutexLocker lock(&gTinyCan->mutex);
    gTinyCan->channels.append(this);
}

TinyCanBackendPrivate::~TinyCanBackendPrivate()
{
    cleanupDriver();

    QMutexLocker lock(&gTinyCan->mutex);
    gTinyCan->channels.removeAll(this);
}

struct BitrateItem
{
    int bitrate;
    int code;
};

struct BitrateLessFunctor
{
    bool operator()( const BitrateItem &item1, const BitrateItem &item2) const
    {
        return item1.bitrate < item2.bitrate;
    }
};

static int bitrateCodeFromBitrate(int bitrate)
{
    static const BitrateItem bitratetable[] = {
        { 10000, CAN_10K_BIT },
        { 20000, CAN_20K_BIT },
        { 50000, CAN_50K_BIT },
        { 100000, CAN_100K_BIT },
        { 125000, CAN_125K_BIT },
        { 250000, CAN_250K_BIT },
        { 500000, CAN_500K_BIT },
        { 800000, CAN_800K_BIT },
        { 1000000, CAN_1M_BIT }
    };

    static const BitrateItem *endtable = bitratetable + (sizeof(bitratetable) / sizeof(*bitratetable));

    const BitrateItem item = { bitrate , 0 };
    const BitrateItem *where = std::lower_bound(bitratetable, endtable, item, BitrateLessFunctor());
    return where != endtable ? where->code : -1;
}

bool TinyCanBackendPrivate::open()
{
    Q_Q(TinyCanBackend);

    {
        char options[] = "AutoConnect=1;AutoReopen=0";
        const int ret = ::CanSetOptions(options);
        if (Q_UNLIKELY(ret < 0)) {
            q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ConnectionError);
            return false;
        }
    }

    {
        const int ret = ::CanDeviceOpen(channelIndex, nullptr);
        if (Q_UNLIKELY(ret < 0)) {
            q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ConnectionError);
            return false;
        }
    }

    {
        const int ret = ::CanSetMode(channelIndex, OP_CAN_START, CAN_CMD_ALL_CLEAR);
        if (Q_UNLIKELY(ret < 0)) {
            q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ConnectionError);
            ::CanDeviceClose(channelIndex);
            return false;
        }
    }

    writeNotifier = new TinyCanWriteNotifier(this, q);
    writeNotifier->setInterval(0);

    isOpen = true;
    return true;
}

void TinyCanBackendPrivate::close()
{
    Q_Q(TinyCanBackend);

    delete writeNotifier;
    writeNotifier = nullptr;

    const int ret = ::CanDeviceClose(channelIndex);
    if (Q_UNLIKELY(ret < 0))
        q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ConnectionError);

    isOpen = false;
}

bool TinyCanBackendPrivate::setConfigurationParameter(int key, const QVariant &value)
{
    Q_Q(TinyCanBackend);

    switch (key) {
    case QCanBusDevice::BitRateKey:
        return setBitRate(value.toInt());
    default:
        q->setError(TinyCanBackend::tr("Unsupported configuration key: %1").arg(key),
                    QCanBusDevice::ConfigurationError);
        return false;
    }
}

// These error codes taked from the errors.h file, which
// exists only in linux sources.
QString TinyCanBackendPrivate::systemErrorString(int errorCode)
{
    switch (errorCode) {
    case 0:
        return TinyCanBackend::tr("No error");
    case -1:
        return TinyCanBackend::tr("Driver not initialized");
    case -2:
        return TinyCanBackend::tr("Invalid parameters values were passed");
    case -3:
        return TinyCanBackend::tr("Invalid index value");
    case -4:
        return TinyCanBackend::tr("More invalid CAN-channel");
    case -5:
        return TinyCanBackend::tr("General error");
    case -6:
        return TinyCanBackend::tr("The FIFO cannot be written");
    case -7:
        return TinyCanBackend::tr("The buffer cannot be written");
    case -8:
        return TinyCanBackend::tr("The FIFO cannot be read");
    case -9:
        return TinyCanBackend::tr("The buffer cannot be read");
    case -10:
        return TinyCanBackend::tr("Variable not found");
    case -11:
        return TinyCanBackend::tr("Reading of the variable does not permit");
    case -12:
        return TinyCanBackend::tr("Reading buffer for variable too small");
    case -13:
        return TinyCanBackend::tr("Writing of the variable does not permit");
    case -14:
        return TinyCanBackend::tr("The string/stream to be written is to majority");
    case -15:
        return TinyCanBackend::tr("Fell short min of value");
    case -16:
        return TinyCanBackend::tr("Max value crossed");
    case -17:
        return TinyCanBackend::tr("Access refuses");
    case -18:
        return TinyCanBackend::tr("Invalid value of CAN speed");
    case -19:
        return TinyCanBackend::tr("Invalid value of baud rate");
    case -20:
        return TinyCanBackend::tr("Value not put");
    case -21:
        return TinyCanBackend::tr("No connection to the hardware");
    case -22:
        return TinyCanBackend::tr("Communication error to the hardware");
    case -23:
        return TinyCanBackend::tr("Hardware sends wrong number of parameters");
    case -24:
        return TinyCanBackend::tr("Not enough main memory");
    case -25:
        return TinyCanBackend::tr("The system cannot provide the enough resources");
    case -26:
        return TinyCanBackend::tr("A system call returns with an error");
    case -27:
        return TinyCanBackend::tr("The main thread is occupied");
    case -28:
        return TinyCanBackend::tr("User allocated memory not found");
    case -29:
        return TinyCanBackend::tr("The main thread cannot be launched");
        // the codes -30...-33 are skipped, as they belongs to sockets
    default:
        return TinyCanBackend::tr("Unknown error");
    }
}

static int channelIndexFromName(const QString &interfaceName)
{
    if (interfaceName == QStringLiteral("can0.0"))
        return INDEX_CAN_KANAL_A;
    else if (interfaceName == QStringLiteral("can0.1"))
        return INDEX_CAN_KANAL_B;
    else
        return INDEX_INVALID;
}

void TinyCanBackendPrivate::setupChannel(const QString &interfaceName)
{
    channelIndex = channelIndexFromName(interfaceName);
}

// Calls only in constructor
void TinyCanBackendPrivate::setupDefaultConfigurations()
{
    Q_Q(TinyCanBackend);

    q->setConfigurationParameter(QCanBusDevice::BitRateKey, 500000);
}

void TinyCanBackendPrivate::startWrite()
{
    Q_Q(TinyCanBackend);

    if (!q->hasOutgoingFrames()) {
        writeNotifier->stop();
        return;
    }

    const QCanBusFrame frame = q->dequeueOutgoingFrame();
    const QByteArray payload = frame.payload();

    TCanMsg message;
    ::memset(&message, 0, sizeof(message));

    if (Q_UNLIKELY(payload.size() > int(sizeof(message.Data.Bytes)))) {
        qCWarning(QT_CANBUS_PLUGINS_TINYCAN, "Cannot write frame with payload size %d.", payload.size());
    } else {
        message.Id = frame.frameId();
        message.Flags.Flag.Len = payload.size();
        message.Flags.Flag.Error = (frame.frameType() == QCanBusFrame::ErrorFrame);
        message.Flags.Flag.RTR = (frame.frameType() == QCanBusFrame::RemoteRequestFrame);
        message.Flags.Flag.TxD = 1;
        message.Flags.Flag.EFF = frame.hasExtendedFrameFormat();

        const qint32 messagesToWrite = 1;
        ::memcpy(message.Data.Bytes, payload.constData(), sizeof(message.Data.Bytes));
        const int ret = ::CanTransmit(channelIndex, &message, messagesToWrite);
        if (Q_UNLIKELY(ret < 0))
            q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::WriteError);
        else
            emit q->framesWritten(messagesToWrite);
    }

    if (q->hasOutgoingFrames() && !writeNotifier->isActive())
        writeNotifier->start();
}

// this method is called from the different thread!
void TinyCanBackendPrivate::startRead()
{
    Q_Q(TinyCanBackend);

    QVector<QCanBusFrame> newFrames;

    for (;;) {
        if (!::CanReceiveGetCount(channelIndex))
            break;

        TCanMsg message;
        ::memset(&message, 0, sizeof(message));

        const int messagesToRead = 1;
        const int ret = ::CanReceive(channelIndex, &message, messagesToRead);
        if (Q_UNLIKELY(ret < 0)) {
            q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ReadError);

            TDeviceStatus status;
            ::memset(&status, 0, sizeof(status));

            if (::CanGetDeviceStatus(channelIndex, &status) < 0) {
                q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ReadError);
            } else {
                if (status.CanStatus == CAN_STATUS_BUS_OFF) {
                    qCWarning(QT_CANBUS_PLUGINS_TINYCAN, "CAN bus is in off state, trying to reset the bus.");
                    resetController();
                }
            }

            continue;
        }

        QCanBusFrame frame(message.Id, QByteArray(reinterpret_cast<char *>(message.Data.Bytes),
                                                  int(message.Flags.Flag.Len)));
        frame.setTimeStamp(QCanBusFrame::TimeStamp(message.Time.Sec, message.Time.USec));
        frame.setExtendedFrameFormat(message.Flags.Flag.EFF);

        if (message.Flags.Flag.Error)
            frame.setFrameType(QCanBusFrame::ErrorFrame);
        else if (message.Flags.Flag.RTR)
            frame.setFrameType(QCanBusFrame::RemoteRequestFrame);
        else
            frame.setFrameType(QCanBusFrame::DataFrame);

        newFrames.append(std::move(frame));
    }

    q->enqueueReceivedFrames(newFrames);
}

void TinyCanBackendPrivate::startupDriver()
{
    Q_Q(TinyCanBackend);

    if (driverRefCount == 0) {
        const int ret = ::CanInitDriver(nullptr);
        if (Q_UNLIKELY(ret < 0)) {
            q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ConnectionError);
            return;
        }

        ::CanSetRxEventCallback(&canRxEventCallback);
        ::CanSetEvents(EVENT_ENABLE_RX_MESSAGES);

    } else if (Q_UNLIKELY(driverRefCount < 0)) {
        qCCritical(QT_CANBUS_PLUGINS_TINYCAN, "Wrong driver reference counter: %d",
                   driverRefCount);
        return;
    }

    ++driverRefCount;
}

void TinyCanBackendPrivate::cleanupDriver()
{
    --driverRefCount;

    if (Q_UNLIKELY(driverRefCount < 0)) {
        qCCritical(QT_CANBUS_PLUGINS_TINYCAN, "Wrong driver reference counter: %d",
                   driverRefCount);
        driverRefCount = 0;
    } else if (driverRefCount == 0) {
        ::CanSetEvents(EVENT_DISABLE_ALL);
        ::CanDownDriver();
    }
}

void TinyCanBackendPrivate::resetController()
{
    Q_Q(TinyCanBackend);
    qint32 ret = ::CanSetMode(channelIndex, OP_CAN_RESET, CAN_CMD_NONE);
    if (Q_UNLIKELY(ret < 0)) {
        const QString errorString = systemErrorString(ret);
        qCWarning(QT_CANBUS_PLUGINS_TINYCAN, "Cannot perform hardware reset: %ls",
                  qUtf16Printable(errorString));
        q->setError(errorString, QCanBusDevice::CanBusError::ConfigurationError);
    }
}

bool TinyCanBackendPrivate::setBitRate(int bitrate)
{
    Q_Q(TinyCanBackend);

    const int bitrateCode = bitrateCodeFromBitrate(bitrate);
    if (Q_UNLIKELY(bitrateCode == -1)) {
        q->setError(TinyCanBackend::tr("Unsupported bitrate value"),
                    QCanBusDevice::ConfigurationError);
        return false;
    }

    if (isOpen) {
        const int ret = ::CanSetSpeed(channelIndex, bitrateCode);
        if (Q_UNLIKELY(ret < 0)) {
            q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ConfigurationError);
            return false;
        }
    }

    return true;
}

TinyCanBackend::TinyCanBackend(const QString &name, QObject *parent)
    : QCanBusDevice(parent)
    , d_ptr(new TinyCanBackendPrivate(this))
{
    Q_D(TinyCanBackend);

    d->setupChannel(name);
    d->setupDefaultConfigurations();

    std::function<void()> f = std::bind(&TinyCanBackend::resetController, this);
    setResetControllerFunction(f);
}

TinyCanBackend::~TinyCanBackend()
{
    close();
    delete d_ptr;
}

bool TinyCanBackend::open()
{
    Q_D(TinyCanBackend);

    if (!d->isOpen) {
        if (!d->open()) {
            close(); // sets UnconnectedState
            return false;
        }

        // apply all stored configurations
        const auto keys = configurationKeys();
        for (int key : keys) {
            const QVariant param = configurationParameter(key);
            const bool success = d->setConfigurationParameter(key, param);
            if (Q_UNLIKELY(!success)) {
                qCWarning(QT_CANBUS_PLUGINS_TINYCAN, "Cannot apply parameter: %d with value: %ls.",
                          key, qUtf16Printable(param.toString()));
            }
        }
    }

    setState(QCanBusDevice::ConnectedState);
    return true;
}

void TinyCanBackend::close()
{
    Q_D(TinyCanBackend);

    d->close();

    setState(QCanBusDevice::UnconnectedState);
}

void TinyCanBackend::setConfigurationParameter(int key, const QVariant &value)
{
    Q_D(TinyCanBackend);

    if (d->setConfigurationParameter(key, value))
        QCanBusDevice::setConfigurationParameter(key, value);
}

bool TinyCanBackend::writeFrame(const QCanBusFrame &newData)
{
    Q_D(TinyCanBackend);

    if (Q_UNLIKELY(state() != QCanBusDevice::ConnectedState))
        return false;

    if (Q_UNLIKELY(!newData.isValid())) {
        setError(tr("Cannot write invalid QCanBusFrame"), QCanBusDevice::WriteError);
        return false;
    }

    if (Q_UNLIKELY(newData.frameType() != QCanBusFrame::DataFrame
            && newData.frameType() != QCanBusFrame::RemoteRequestFrame
            && newData.frameType() != QCanBusFrame::ErrorFrame)) {
        setError(tr("Unable to write a frame with unacceptable type"),
                 QCanBusDevice::WriteError);
        return false;
    }

    // CAN FD frame format not supported at this stage
    if (Q_UNLIKELY(newData.hasFlexibleDataRateFormat())) {
        setError(tr("CAN FD frame format not supported."), QCanBusDevice::WriteError);
        return false;
    }

    enqueueOutgoingFrame(newData);

    if (!d->writeNotifier->isActive())
        d->writeNotifier->start();

    return true;
}

// TODO: Implement me
QString TinyCanBackend::interpretErrorFrame(const QCanBusFrame &errorFrame)
{
    Q_UNUSED(errorFrame);

    return QString();
}

void TinyCanBackend::resetController()
{
    Q_D(TinyCanBackend);
    d->resetController();
}

QT_END_NAMESPACE
