// SPDX-FileCopyrightText: 2023 Plata Hill <plata.hill@kdemail.net>
// SPDX-License-Identifier: LGPL-2.1-or-later

#include "../src/xmltvfetcher.h"

#include "../src/TellySkoutSettings.h"

#include <QSignalSpy>
#include <QStandardPaths>
#include <QString>
#include <QTest>

class XmltvFetcherTest : public QObject
{
    Q_OBJECT

private:
    const QString m_dataPath = QFINDTESTDATA("data/xmltvfetcher/test.xml");

private Q_SLOTS:
    void initTestCase()
    {
        // xmltv: : Europe/Berlin (UTC+1), DB: UTC
        // check that start/stop times are displayed correctly in Europe/Athens (UTC+2 = EET-2)
        qputenv("TZ", "EET-2");
        QStandardPaths::setTestModeEnabled(true);

        TellySkoutSettings::setXmltvFile(m_dataPath);
    }

    void testFetchGroups()
    {
        XmltvFetcher fetcher;
        QVector<GroupData> data;
        bool callbackCalled = false;
        bool errorCallbackCalled = false;
        fetcher.fetchGroups(
            [&data, &callbackCalled](const QVector<GroupData> &groups) {
                data = groups;
                callbackCalled = true;
            },
            [&errorCallbackCalled](Error) {
                errorCallbackCalled = true;
            });
        QCOMPARE(callbackCalled, true);
        QCOMPARE(errorCallbackCalled, false);
        QCOMPARE(data.size(), 1);
        const GroupData &group = data.at(0);
        QCOMPARE(group.m_id.value(), QStringLiteral("xmltv"));
        QCOMPARE(group.m_name, QStringLiteral("XMLTV"));
        QCOMPARE(group.m_url, m_dataPath);
    }

    void testFetchGroup()
    {
        XmltvFetcher fetcher;
        const GroupData group{GroupId(QStringLiteral("xmltv")), QStringLiteral("XMLTV"), m_dataPath};
        QList<ChannelData> data;
        bool callbackCalled = false;
        bool errorCallbackCalled = false;
        fetcher.fetchGroup(
            group.m_url,
            group.m_id,
            [&data, &callbackCalled](const QList<ChannelData> &channels) {
                data = channels;
                callbackCalled = true;
            },
            [&errorCallbackCalled](Error) {
                errorCallbackCalled = true;
            });
        QCOMPARE(callbackCalled, true);
        QCOMPARE(errorCallbackCalled, false);
        QCOMPARE(data.size(), 2);
    }

    void testFetchProgram()
    {
        const ChannelId channelId(QStringLiteral("channel1"));

        XmltvFetcher fetcher;
        QVector<ProgramData> data;
        bool callbackCalled = false;
        bool errorCallbackCalled = false;
        fetcher.fetchProgram(
            channelId,
            [&data, &callbackCalled](const QVector<ProgramData> &programs) {
                data = programs;
                callbackCalled = true;
            },
            [&errorCallbackCalled](Error) {
                errorCallbackCalled = true;
            });
        QCOMPARE(callbackCalled, true);
        QCOMPARE(errorCallbackCalled, false);
        QCOMPARE(data.size(), 2);

        QCOMPARE(data.at(0).m_id, ProgramId(QStringLiteral("channel1_1672182000")));
        QCOMPARE(data.at(0).m_url, QStringLiteral(""));
        QCOMPARE(data.at(0).m_channelId, channelId);
        QCOMPARE(data.at(0).m_startTime, QDateTime::fromString(QStringLiteral("2022-12-28T01:00:00"), Qt::ISODate));
        QCOMPARE(data.at(0).m_stopTime, QDateTime::fromString(QStringLiteral("2022-12-28T07:00:00"), Qt::ISODate));
        QCOMPARE(data.at(0).m_title, QStringLiteral("Title 1"));
        QCOMPARE(data.at(0).m_subtitle, QStringLiteral("Subtitle 1"));
        QCOMPARE(data.at(0).m_description, QStringLiteral("Description 1"));
        QCOMPARE(data.at(0).m_descriptionFetched, true);
        QCOMPARE(data.at(0).m_categories.at(0), QStringLiteral("Category 1"));

        QCOMPARE(data.at(1).m_id, ProgramId(QStringLiteral("channel1_1672203600")));
        QCOMPARE(data.at(1).m_url, QStringLiteral(""));
        QCOMPARE(data.at(1).m_channelId, channelId);
        QCOMPARE(data.at(1).m_startTime, QDateTime::fromString(QStringLiteral("2022-12-28T07:00:00"), Qt::ISODate));
        QCOMPARE(data.at(1).m_stopTime, QDateTime::fromString(QStringLiteral("2022-12-28T10:00:00"), Qt::ISODate));
        QCOMPARE(data.at(1).m_title, QStringLiteral("Title 2"));
        QCOMPARE(data.at(1).m_subtitle, QStringLiteral("Subtitle 2"));
        QCOMPARE(data.at(1).m_description, QStringLiteral("Description 2"));
        QCOMPARE(data.at(1).m_descriptionFetched, true);
        QCOMPARE(data.at(1).m_categories.at(0), QStringLiteral("Category 2"));
    }

    void testFetchProgramDescription()
    {
        const ChannelId channelId(QStringLiteral("channel1"));
        ProgramId programId;

        XmltvFetcher fetcher;
        QString data;
        bool callbackCalled = false;
        bool errorCallbackCalled = false;
        fetcher.fetchProgramDescription(
            channelId,
            ProgramId(QStringLiteral("channel1_1672182000")),
            QStringLiteral(""),
            [&data, &callbackCalled](const QString &description) {
                data = description;
                callbackCalled = true;
            },
            [&errorCallbackCalled](Error) {
                errorCallbackCalled = true;
            });
        // nothing done, description already known after fetchProgram()
        QCOMPARE(callbackCalled, false);
        QCOMPARE(errorCallbackCalled, false);
        QCOMPARE(data, QStringLiteral(""));
    }
};

QTEST_GUILESS_MAIN(XmltvFetcherTest)

#include "xmltvfetchertest.moc"
