/****************************************************************************
**
** 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$
**
****************************************************************************/

#ifndef QMODBUSADU_P_H
#define QMODBUSADU_P_H

#include <QtSerialBus/qmodbuspdu.h>

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

QT_BEGIN_NAMESPACE

class QModbusSerialAdu
{
public:
    enum Type {
        Ascii,
        Rtu
    };

    inline QModbusSerialAdu(Type type, const QByteArray &data)
        : m_type(type), m_data(data), m_rawData(data)
    {
        if (m_type == Ascii)
            m_data = QByteArray::fromHex(m_data.mid(1, m_data.size() - 3));
    }

    inline int size() const {
        if (m_type == Ascii)
            return m_data.size() - 1; // one byte, LRC
        return m_data.size() - 2; // two bytes, CRC
    }
    inline QByteArray data() const { return m_data.left(size()); }

    inline int rawSize() const { return m_rawData.size(); }
    inline QByteArray rawData() const { return m_rawData; }

    inline int serverAddress() const {
        Q_ASSERT_X(!m_data.isEmpty(), "QModbusAdu::serverAddress()", "Empty ADU.");
        return quint8(m_data.at(0));
    }

    inline QModbusPdu pdu() const {
        Q_ASSERT_X(!m_data.isEmpty(), "QModbusAdu::pdu()", "Empty ADU.");
        return QModbusPdu(QModbusPdu::FunctionCode(m_data.at(1)), m_data.mid(2, size() - 2));
    }

    template <typename T>
    auto checksum() const -> decltype(T()) {
        Q_ASSERT_X(!m_data.isEmpty(), "QModbusAdu::checksum()", "Empty ADU.");
        if (m_type == Ascii)
            return quint8(m_data[m_data.size() - 1]);
        return quint16(quint8(m_data[m_data.size() - 2]) << 8 | quint8(m_data[m_data.size() - 1]));
    }

    inline bool matchingChecksum() const {
        Q_ASSERT_X(!m_data.isEmpty(), "QModbusAdu::matchingChecksum()", "Empty ADU.");
        if (m_type == Ascii)
            return QModbusSerialAdu::calculateLRC(data(), size()) == checksum<quint8>();
        return QModbusSerialAdu::calculateCRC(data(), size()) == checksum<quint16>();
    }

    /*!
        \internal
        \fn quint8 QModbusSerialAdu::calculateLRC(const char *data, qint32 len)

        Returns the LRC checksum of the first \a len bytes of \a data. The checksum is independent
        of the byte order (endianness).
    */
    inline static quint8 calculateLRC(const char *data, qint32 len)
    {
        quint32 lrc = 0;
        while (len--)
            lrc += *data++;
        return -(quint8(lrc));
    }

    /*!
        \internal
        \fn quint16 QModbusSerialAdu::calculateCRC(const char *data, qint32 len) const

        Returns the CRC checksum of the first \a len bytes of \a data.

        \note The code used by the function was generated with pycrc. There is no copyright assigned
        to the generated code, however, the author of the script requests to show the line stating
        that the code was generated by pycrc (see implementation).
    */
    inline static quint16 calculateCRC(const char *data, qint32 len)
    {
        // Generated by pycrc v0.8.3, https://pycrc.org
        // Width = 16, Poly = 0x8005, XorIn = 0xffff, ReflectIn = True,
        // XorOut = 0x0000, ReflectOut = True, Algorithm = bit-by-bit-fast

        quint16 crc = 0xFFFF;
        while (len--) {
            const quint8 c = *data++;
            for (qint32 i = 0x01; i & 0xFF; i <<= 1) {
                bool bit = crc & 0x8000;
                if (c & i)
                    bit = !bit;
                crc <<= 1;
                if (bit)
                    crc ^= 0x8005;
            }
            crc &= 0xFFFF;
        }
        crc = crc_reflect(crc & 0xFFFF, 16) ^ 0x0000;
        return (crc >> 8) | (crc << 8); // swap bytes
    }

    inline static QByteArray create(Type type, int serverAddress, const QModbusPdu &pdu,
                                    char delimiter = '\n') {
        QByteArray result;
        QDataStream out(&result, QIODevice::WriteOnly);
        out << quint8(serverAddress) << pdu;

        if (type == Ascii) {
            out << calculateLRC(result, result.size());
            return ":" + result.toHex() + "\r" + delimiter;
        } else {
            out << calculateCRC(result, result.size());
        }
        return result;
    }

private:
    inline static quint16 crc_reflect(quint16 data, qint32 len)
    {
        // Generated by pycrc v0.8.3, https://pycrc.org
        // Width = 16, Poly = 0x8005, XorIn = 0xffff, ReflectIn = True,
        // XorOut = 0x0000, ReflectOut = True, Algorithm = bit-by-bit-fast

        quint16 ret = data & 0x01;
        for (qint32 i = 1; i < len; i++) {
            data >>= 1;
            ret = (ret << 1) | (data & 0x01);
        }
        return ret;
    }

private:
    Type m_type = Rtu;
    QByteArray m_data;
    QByteArray m_rawData;
};

QT_END_NAMESPACE

#endif // QMODBUSADU_P_H
