#include "Device/Coord/ICoordSystem.h"
#include "GUI/Model/Axis/BasicAxisItem.h"
#include "GUI/Model/Data/DataItemUtil.h"
#include "GUI/Model/Detector/RectangularDetectorItem.h"
#include "GUI/Model/Device/InstrumentItems.h"
#include "GUI/Model/Device/RealItem.h"
#include "GUI/Model/Model/RealModel.h"
#include "GUI/Model/Project/LinkInstrumentManager.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include "Tests/GTestWrapper/google_test.h"
#include "Tests/Unit/GUI/Utils.h"
#include <QSignalSpy>
#include <QTest>

QList<RealItem*> linkedRealDataItems(RealModel& realModel, const InstrumentItem* instrumentItem)
{
    ASSERT(instrumentItem);

    QList<RealItem*> result;
    for (auto* realItem : realModel.realItems()) {
        const QString linkedIdentifier = realItem->instrumentId();
        const QString instrumentIdentifier = instrumentItem->id();

        if (linkedIdentifier == instrumentIdentifier)
            result.append(realItem);
    }
    return result;
}

TEST(TestLinkInstrument, canLinkToInstrument)
{
    ProjectDocument document;

    // populating instrument model
    auto* instrument = document.instrumentModel()->addInstrumentItem<GISASInstrumentItem>();
    const QString identifier = instrument->id();
    ASSERT_TRUE(!identifier.isEmpty());

    // populating real data model, setting intensity data
    RealItem* realData = UTest::GUI::createRealData("RealData", *document.realModel());
    const auto converter = instrument->createCoordSystem();
    ASSERT_TRUE(converter);
    GUI::Model::DataItemUtil::createDefaultDetectorMap(realData->dataItem(), *converter);

    ASSERT_TRUE(
        document.linkInstrumentManager()->canLinkDataToInstrument(realData, identifier, nullptr));

    // making link
    realData->linkToInstrument(instrument);
    EXPECT_EQ(linkedRealDataItems(*document.realModel(), instrument), QList<RealItem*>()
                                                                          << realData);

    // changing detector type and checking that link remain
    instrument->setDetectorItemType<RectangularDetectorItem>();
    EXPECT_EQ(linkedRealDataItems(*document.realModel(), instrument), QList<RealItem*>()
                                                                          << realData);

    // changing detector binning and checking that link is destroyed
    auto* detectorItem = dynamic_cast<RectangularDetectorItem*>(instrument->detectorItem());
    detectorItem->setXSize(10);
    document.multiNotifier()->notifyInstrumentChanged(instrument);

    EXPECT_EQ(linkedRealDataItems(*document.realModel(), instrument), QList<RealItem*>());
    EXPECT_EQ(realData->instrumentId(), QString());
}
