'use strict';

import {expect} from "chai"

import {ResourceManager} from "../../../source/dom/resourcemanager.mjs";
import {cleanupDOMFromTesting, initMutationObserverForTesting} from "../../util/cleanupdom.mjs";
import {initJSDOM} from "../../util/jsdom.mjs";

const validDataURL = 'https://example.test/data.json';
const validExampleURL = 'https://example.test/example.json';
const allowedOrigins = ['https://example.test'];

describe('ResourceManager', function () {

    let fetchReference, returnStatus;

    before(function (done) {
        initJSDOM().then(() => {
            done()
        }).catch(e => done(e));
    });

    afterEach(() => {
        globalThis['fetch'] = fetchReference;
        cleanupDOMFromTesting();
    })

    beforeEach(() => {

        initMutationObserverForTesting()

        returnStatus = 200;
        fetchReference = globalThis['fetch'];
        globalThis['fetch'] = function (url, options) {

            if (!url) throw new Error('missing url')

            return new Promise((resolve, reject) => {
                resolve({
                    text: function () {
                        return JSON.stringify({
                            a: "test"
                        })
                    },
                    status: returnStatus
                });
            })

        };

    })

    describe('new', function () {
        it('new ResourceManager() should return ResourceManager object', function () {
            let d = new ResourceManager();
            expect(d).to.be.instanceOf(ResourceManager);
        });
    });

    describe('load resources', function () {

        let manager;

        beforeEach(() => {
            manager = new ResourceManager();
        })

        it('add script should instance of ResourceManager', function () {
            expect(manager.addScript('/example.js')).to.be.instanceOf(ResourceManager);
        });

        it('add style should instance of ResourceManager', function () {
            expect(manager.addStylesheet('/style.js')).to.be.instanceOf(ResourceManager);
        });

        it('add data should instance of ResourceManager', function () {
            expect(manager.addData(validDataURL, {allowedOrigins})).to.be.instanceOf(ResourceManager);
        });

        describe('connect resources', function () {
            it('add script and connect should instance of ResourceManager', function () {
                expect(manager.addScript('/example.js').connect()).to.be.instanceOf(ResourceManager);
            });

            it('add style and connect should instance of ResourceManager', function () {
                expect(manager.addStylesheet('/style.js').connect()).to.be.instanceOf(ResourceManager);
            });

            it('add data and connect  should instance of ResourceManager', function () {
                expect(manager.addData(validDataURL, {allowedOrigins}).connect()).to.be.instanceOf(ResourceManager);
            });
        })


        describe('check availability resources', function () {
            it('add script and check availability should return Promise', function () {
                expect(manager.addScript('/example.js').available()).to.be.instanceOf(Promise);
            });

            it('add style and check availability should should return Promise', function () {
                expect(manager.addStylesheet('/style.js').available()).to.be.instanceOf(Promise);
            });

            it('add data and check availability  should should return Promise', function () {
                expect(manager.addData(validDataURL, {allowedOrigins}).available()).to.be.instanceOf(Promise);
            });
        })

        describe('check availability example.json', function () {
            it('add data and check content', function (done) {
                manager.addData(validExampleURL, {allowedOrigins}).connect().available().then(r => {
                    expect(document.querySelector('html').outerHTML).contains('>{"a":"test"}</script></head>');
                    done();
                }).catch(e => done(e));
            });

        })

    });


});
