#include "GUI/Model/Device/InstrumentItems.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include "Tests/GTestWrapper/google_test.h"
#include <QSignalSpy>

Q_DECLARE_METATYPE(const InstrumentItem*)

//! Checks whether instrumentAddedRemoved will be emitted as expected

TEST(TestInstrumentCollection, instrumentAddedRemoved)
{
    ProjectDocument document;

    QSignalSpy spy(document.multiNotifier(), SIGNAL(instrumentAddedOrRemoved()));
    EXPECT_TRUE(spy.isValid());

    // populating instrument model
    auto* p = document.multiNotifier()->addInstrumentItem<GISASInstrumentItem>();

    // checking that a signal was emitted about the new instrument
    EXPECT_EQ(spy.count(), 1);

    // removing instrument
    document.multiNotifier()->removeInstrument(p);
    EXPECT_EQ(spy.count(), 2);
}

//! Test whether instrumentChanged will be emitted as expected
TEST(TestInstrumentCollection, instrumentChanged)
{
    qRegisterMetaType<const InstrumentItem*>();
    ProjectDocument document;

    // populating instrument model
    auto* instrument1 = document.multiNotifier()->addInstrumentItem<GISASInstrumentItem>();
    auto* instrument2 = document.multiNotifier()->addInstrumentItem<SpecularInstrumentItem>();

    QSignalSpy spy(document.multiNotifier(), SIGNAL(instrumentChanged(const InstrumentItem*)));
    EXPECT_TRUE(spy.isValid());

    // change name of instrument 1
    document.multiNotifier()->setInstrumentName(instrument1, "A");
    EXPECT_EQ(spy.count(), 1);
    const auto* instr = qvariant_cast<const InstrumentItem*>(spy.at(0).at(0));
    EXPECT_EQ(instr, instrument1);

    // change other properties, e.g. id
    instrument1->setId("xxxxx");
    document.multiNotifier()->notifyInstrumentChanged(instrument1);
    EXPECT_EQ(spy.count(), 2);

    // change name of instrument 2
    document.multiNotifier()->setInstrumentName(instrument2, "B");
    EXPECT_EQ(spy.count(), 3);
    instr = qvariant_cast<const InstrumentItem*>(spy.at(2).at(0));
    EXPECT_EQ(instr, instrument2);

    // Add another instrument
    auto* instrument3 = document.multiNotifier()->addInstrumentItem<OffspecInstrumentItem>();

    // Change instrument2
    document.multiNotifier()->setInstrumentName(instrument2, "BB");
    EXPECT_EQ(spy.count(), 4);
    instr = qvariant_cast<const InstrumentItem*>(spy.at(3).at(0));
    EXPECT_EQ(instr, instrument2);

    // Change instrument3
    document.multiNotifier()->setInstrumentName(instrument3, "C");
    EXPECT_EQ(spy.count(), 5);
    instr = qvariant_cast<const InstrumentItem*>(spy.at(4).at(0));
    EXPECT_EQ(instr, instrument3);
}
