/***************************************************************************
                          tst_mainqsoentrywidget.h  -  description
                             -------------------
    begin                : Jan 2021
    copyright            : (C) 2021 by Jaime Robles
    email                : jaime@robles.es
 ***************************************************************************/

/*****************************************************************************
 * This file is part of Testing suite of KLog.                               *
 *                                                                           *
 *    KLog is free software: you can redistribute it and/or modify           *
 *    it under the terms of the GNU General Public License as published by   *
 *    the Free Software Foundation, either version 3 of the License, or      *
 *    (at your option) any later version.                                    *
 *                                                                           *
 *    The testing suite of KLog is distributed in the hope that it will      *
 *    be useful, but WITHOUT ANY WARRANTY; without even the implied          *
 *    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.       *
 *    See the GNU General Public License for more details.                   *
 *                                                                           *
 *    You should have received a copy of the GNU General Public License      *
 *    along with Testing suite of KLog.                                      *
 *    If not, see <https://www.gnu.org/licenses/>.                           *
 *                                                                           *
 *****************************************************************************/

#include <QtTest>
#include "../../src/mainqsoentrywidget.h"
#include "../../src/dataproxy_sqlite.h"
#include "../../src/database/database.h"
#include "../../src/klogdefinitions.h"
#include "../../src/utilities.h"
#include "../../src/qso.h"

class tst_MainQSOEntryWidget : public QObject
{
    Q_OBJECT

public:
    tst_MainQSOEntryWidget();
    ~tst_MainQSOEntryWidget();

private slots:
    void initTestCase();
    void cleanupTestCase();
    void test_Constructor();
    void test_CallSign();
    void test_InitialData();
    void test_Bands();
    void test_Modes();
    void test_QSOData();
    void test_QRZSignalEmittedAfterClearAndResameCall();
    void test_QRZSignalDebounce();

private:
    DataProxy_SQLite *dataProxy;
    MainQSOEntryWidget *mainQSOEntryWidget;
};


tst_MainQSOEntryWidget::tst_MainQSOEntryWidget()
{
    dataProxy = new DataProxy_SQLite(Q_FUNC_INFO);
    mainQSOEntryWidget = new MainQSOEntryWidget(dataProxy);
}

tst_MainQSOEntryWidget::~tst_MainQSOEntryWidget(){}

void tst_MainQSOEntryWidget::initTestCase(){}

void tst_MainQSOEntryWidget::cleanupTestCase(){}

void tst_MainQSOEntryWidget::test_Constructor()
{
    QVERIFY((mainQSOEntryWidget->getQrz()).length () == 0);
}

void tst_MainQSOEntryWidget::test_CallSign()
{
    mainQSOEntryWidget->clear ();
    mainQSOEntryWidget->setQRZ("EA4K");
    QVERIFY((mainQSOEntryWidget->getQrz()).length () == 4);
}

void tst_MainQSOEntryWidget::test_InitialData()
{
    QString mode = mainQSOEntryWidget->getMode();
    QStringList modes, bands;
    modes.clear();
    bands.clear();
    bands << "10M" << "15M" << "20M" << "40M" << "80M" << "160M";
    modes << "SSB" << "CW" << "RTTY" << "USB" << "LSB";
    mainQSOEntryWidget->setModes (modes);
    mainQSOEntryWidget->setBands (bands);
    QVERIFY(mainQSOEntryWidget->getModes().length() == modes.length ());
    QVERIFY(mainQSOEntryWidget->getDate()== QDate::currentDate());
    //qDebug() << mainQSOEntryWidget->getBand(-1) ;
    // qVERIFY(mainQSOEntryWidget->getBand(-1) == "20M");
    QVERIFY(mainQSOEntryWidget->getBand(0) == "160M");
    QVERIFY(mainQSOEntryWidget->getBand(1) == "80M");
    QVERIFY(mainQSOEntryWidget->getBand(2) == "40M");
    QVERIFY(mainQSOEntryWidget->getBand(3) == "20M");
    QVERIFY(mainQSOEntryWidget->getBand(4) == "15M");
    QVERIFY(mainQSOEntryWidget->getBand(5) == "10M");
    // qVERIFY(mainQSOEntryWidget->getBand(6) == "");
    // qVERIFY(mainQSOEntryWidget->getMode(-1) == mode);
    QVERIFY(mainQSOEntryWidget->getMode(0) == "CW");
    QVERIFY(mainQSOEntryWidget->getMode(1) == "LSB");
    QVERIFY(mainQSOEntryWidget->getMode(2) == "RTTY");
    QVERIFY(mainQSOEntryWidget->getMode(3) == "SSB");
    QVERIFY(mainQSOEntryWidget->getMode(4) == "USB");
}

void tst_MainQSOEntryWidget::test_Bands()
{
    QString band = mainQSOEntryWidget->getBand();

    QVERIFY (mainQSOEntryWidget->isBandExisting ("160M") == true);
    QVERIFY (mainQSOEntryWidget->isBandExisting ("70M") == false);
    QString currentBand = mainQSOEntryWidget->getBand ();
    mainQSOEntryWidget->setBand ("10M");
    QVERIFY (mainQSOEntryWidget->getBand() == "10M");
    mainQSOEntryWidget->setBand ("15M");
    QVERIFY (mainQSOEntryWidget->getBand() == "15M");
    mainQSOEntryWidget->setBand ("20M");
    QVERIFY (mainQSOEntryWidget->getBand() == "20M");
    mainQSOEntryWidget->setBand ("40M");
    QVERIFY (mainQSOEntryWidget->getBand() == "40M");
    mainQSOEntryWidget->setBand ("80M");
    QVERIFY (mainQSOEntryWidget->getBand() == "80M");
    mainQSOEntryWidget->setBand ("160M");
    QVERIFY (mainQSOEntryWidget->getBand() == "160M");
    //qDebug() <<mainQSOEntryWidget->getBand() ;
    //mainQSOEntryWidget->setBand("12M"); // Trying to select a band that is not in the list
    mainQSOEntryWidget->setBand (band);
    QVERIFY (mainQSOEntryWidget->getBand() == band);
    //qDebug() << mainQSOEntryWidget->getBand() ;
    mainQSOEntryWidget->selectDefaultBand ();
    //qDebug() << "DefaultBand: " << mainQSOEntryWidget->getBand() ;
    QVERIFY (mainQSOEntryWidget->getBand() == currentBand);
}

void tst_MainQSOEntryWidget::test_Modes()
{
    QVERIFY (mainQSOEntryWidget->isModeExisting ("SSB") == true);
    QVERIFY (mainQSOEntryWidget->isModeExisting ("PSK") == false);
}

void tst_MainQSOEntryWidget::test_QSOData()
{
    QSO qso1;
    QSO qso2;

    qso1.setCall("EA1K");
    qso1.setAge(10);
    mainQSOEntryWidget->setQRZ("EA2K");

    //qDebug() << Q_FUNC_INFO << " - 1 - qso1: " << qso1.getCall();
    //qDebug() << Q_FUNC_INFO << " - 1 - qso2: " << qso2.getCall();
    //qDebug() << Q_FUNC_INFO << " - 1 - UI  : " << mainQSOEntryWidget->getQrz();

    qso2 = mainQSOEntryWidget->getQSOData(qso1);
    //qDebug() << Q_FUNC_INFO << " - 2 - qso1: " << qso1.getCall();
    //qDebug() << Q_FUNC_INFO << " - 2 - qso2: " << qso2.getCall();
    //qDebug() << Q_FUNC_INFO << " - 2 - UI  : " << mainQSOEntryWidget->getQrz();
    QVERIFY2 (qso2.getCall() == mainQSOEntryWidget->getQrz(), "Wrong Call on QSO copy");
}

/*
 *
 * QSO MainQSOEntryWidget::getQSOData(QSO & _qso)
{
    //qDebug() << Q_FUNC_INFO << " -  Call-01   : " << _qso.getCall();

    _qso.setCall(getQrz());
    _qso.setBand(getBand());
    _qso.setMode(dataProxy->getNameFromSubMode (getMode()));
    _qso.setSubmode(getMode());
    _qso.setDateTimeOn(getDateTime());
    return _qso;
}

*/

// Regression test for issue #242:
// slotDelayInputTimedOut had "text = lastQrz" instead of "lastQrz = text",
// which prevented lastQrz from being updated. As a consequence, after calling
// clear() the same callsign would not fire currentQRZSignal again (once the
// bug is properly fixed together with the lastQrz.clear() in clear()).
void tst_MainQSOEntryWidget::test_QRZSignalEmittedAfterClearAndResameCall()
{
    QSignalSpy spy(mainQSOEntryWidget, &MainQSOEntryWidget::currentQRZSignal);

    mainQSOEntryWidget->clear();
    mainQSOEntryWidget->setQRZ("EA4K");
    QTest::qWait(400); // wait for the 300 ms debounce timer

    QVERIFY2(spy.count() > 0, "currentQRZSignal not emitted after first setQRZ");
    int countAfterFirst = spy.count();

    // Simulate what WSJT-X does: clear form (e.g. after logging a QSO) then
    // send the same callsign again.  Without the fix the signal was not emitted
    // the second time.
    mainQSOEntryWidget->clear();
    mainQSOEntryWidget->setQRZ("EA4K");
    QTest::qWait(400);

    QVERIFY2(spy.count() > countAfterFirst,
             "currentQRZSignal not emitted after clear() + re-set of same callsign (regression #242)");
}

// Verify that distinct callsigns each trigger currentQRZSignal and that the
// debounce mechanism (lastQrz) does not swallow a real change.
void tst_MainQSOEntryWidget::test_QRZSignalDebounce()
{
    QSignalSpy spy(mainQSOEntryWidget, &MainQSOEntryWidget::currentQRZSignal);

    mainQSOEntryWidget->clear();
    mainQSOEntryWidget->setQRZ("W1AW");
    QTest::qWait(400);
    QVERIFY2(spy.count() > 0, "currentQRZSignal not emitted for W1AW");
    int countAfterW1AW = spy.count();

    mainQSOEntryWidget->clear();
    mainQSOEntryWidget->setQRZ("EA4K");
    QTest::qWait(400);
    QVERIFY2(spy.count() > countAfterW1AW, "currentQRZSignal not emitted for EA4K after W1AW");
}

QTEST_MAIN(tst_MainQSOEntryWidget)

#include "tst_mainqsoentrywidget.moc"
