// SPDX-License-Identifier: Apache-2.0
import { SimpleConfigSourceFixture } from '../../../fixtures/simple-config-source.fixture.js';
import { LayeredConfig } from '../../../../../src/data/configuration/impl/layered-config.js';
import { expect } from 'chai';
import { IllegalArgumentError } from '../../../../../src/business/errors/illegal-argument-error.js';
import { DuplicateConfigSourceError } from '../../../../../src/data/configuration/api/duplicate-config-source-error.js';
class SimpleObject {
    properties1;
    properties2;
    properties3;
    properties4;
    constructor(properties1, properties2, properties3, properties4) {
        this.properties1 = properties1;
        this.properties2 = properties2;
        this.properties3 = properties3;
        this.properties4 = properties4;
    }
}
describe('LayeredConfig', () => {
    let map1;
    let map2;
    let map3;
    let simpleConfigSourceOrdinal1;
    let simpleConfigSourceOrdinal2;
    let simpleConfigSourceOrdinal3;
    let layeredConfig;
    beforeEach(() => {
        map1 = new Map();
        map2 = new Map();
        map3 = new Map();
        map1.set('key1', 'map1key1value1');
        map1.set('key2', 'map1key2value2');
        map1.set('boolean', 'true');
        map1.set('stringArray', '["map1StringArray"]');
        map2.set('key2', 'map2key2value2');
        map2.set('key3', 'map2key2value3');
        map2.set('number', '42');
        map3.set('key3', 'map3key3value3');
        const simpleObject = new SimpleObject('properties1', 42, true, ['properties4']);
        map2.set('simpleObject', JSON.stringify(simpleObject));
        map1.set('simpleObjectArray', JSON.stringify([simpleObject]));
        simpleConfigSourceOrdinal1 = new SimpleConfigSourceFixture('simpleConfigSource1', 1, 'simpleConfigSource1', undefined, map1);
        simpleConfigSourceOrdinal2 = new SimpleConfigSourceFixture('simpleConfigSource2', 2, 'simpleConfigSource2', undefined, map2);
        simpleConfigSourceOrdinal3 = new SimpleConfigSourceFixture('simpleConfigSource3', 3, 'simpleConfigSource3', undefined, map3);
        layeredConfig = new LayeredConfig([
            simpleConfigSourceOrdinal2,
            simpleConfigSourceOrdinal3,
            simpleConfigSourceOrdinal1,
        ]);
    });
    it('addSource should throw IllegalArgumentError if source is null', () => {
        // eslint-disable-next-line unicorn/no-null
        expect(() => layeredConfig.addSource(null)).to.throw(IllegalArgumentError);
        // eslint-disable-next-line unicorn/no-useless-undefined
        expect(() => layeredConfig.addSource(undefined)).to.throw(IllegalArgumentError);
    });
    it('addSource should throw DuplicateConfigSourceError if source is already present', () => {
        expect(() => layeredConfig.addSource(simpleConfigSourceOrdinal3)).to.throw(DuplicateConfigSourceError);
    });
    it('addSource should not throw if source is not present', () => {
        const newSource = new SimpleConfigSourceFixture('newConfigSource', 4, 'newConfigSource', undefined, new Map());
        const ordinalShiftedSource = new SimpleConfigSourceFixture('newConfigSource', 5, 'newConfigSource', undefined, new Map());
        expect(layeredConfig.sources).to.have.lengthOf(3);
        expect(layeredConfig.sources).to.not.contain(newSource);
        expect(() => layeredConfig.addSource(newSource)).to.not.throw();
        expect(layeredConfig.sources).to.have.lengthOf(4);
        expect(layeredConfig.sources).to.contain(newSource);
        expect(layeredConfig.sources).to.not.contain(ordinalShiftedSource);
        expect(() => layeredConfig.addSource(ordinalShiftedSource)).to.not.throw();
        expect(layeredConfig.sources).to.have.lengthOf(5);
        expect(layeredConfig.sources).to.contain(ordinalShiftedSource);
        expect(() => layeredConfig.addSource(newSource)).to.throw(DuplicateConfigSourceError);
    });
    it('should sort sources by ordinal', () => {
        const propertyMap = layeredConfig.properties();
        expect(propertyMap.get('key1')).to.equal('map1key1value1');
        expect(propertyMap.get('key2')).to.equal('map2key2value2');
        expect(propertyMap.get('key3')).to.equal('map3key3value3');
    });
    it('should return the correct property names', () => {
        const propertyNames = layeredConfig.propertyNames();
        expect(propertyNames.has('key1')).to.be.true;
        expect(propertyNames.has('key2')).to.be.true;
        expect(propertyNames.has('key3')).to.be.true;
    });
    it('should return the correct properties after a refresh', async () => {
        const map3 = new Map();
        map3.set('key1', 'map3key1value1');
        map3.set('key2', 'map3key2value2');
        map3.set('key3', 'map3key3value3');
        map3.set('key4', 'map3key4value4');
        simpleConfigSourceOrdinal3.props2 = map3;
        await layeredConfig.refresh();
        const propertyMap = layeredConfig.properties();
        expect(propertyMap.get('key1')).to.equal('map3key1value1');
        expect(propertyMap.get('key2')).to.equal('map3key2value2');
        expect(propertyMap.get('key3')).to.equal('map3key3value3');
        expect(propertyMap.get('key4')).to.equal('map3key4value4');
    });
    it('should return as a boolean', () => {
        expect(layeredConfig.asBoolean('boolean')).to.be.true;
    });
    it('should return as a number', () => {
        expect(layeredConfig.asNumber('number')).to.equal(42);
    });
    it('should return as a string', () => {
        expect(layeredConfig.asString('key3')).to.equal('map3key3value3');
    });
    it('should return a string array', () => {
        expect(layeredConfig.asStringArray('stringArray')).to.eql(['map1StringArray']);
    });
    it('should return an object', () => {
        const simpleObject = layeredConfig.asObject(SimpleObject, 'simpleObject');
        expect(simpleObject.properties1).to.equal('properties1');
        expect(simpleObject.properties2).to.equal(42);
        expect(simpleObject.properties3).to.be.true;
        expect(simpleObject.properties4).to.eql(['properties4']);
    });
    it('should return an object array', () => {
        const simpleObjectArray = layeredConfig.asObjectArray(SimpleObject, 'simpleObjectArray');
        expect(simpleObjectArray[0].properties1).to.equal('properties1');
        expect(simpleObjectArray[0].properties2).to.equal(42);
        expect(simpleObjectArray[0].properties3).to.be.true;
        expect(simpleObjectArray[0].properties4).to.eql(['properties4']);
    });
    it('primitiveScalar should throw IllegalArgumentError', () => {
        // @ts-expect-error - testing private method
        // eslint-disable-next-line unicorn/no-null
        expect(() => layeredConfig.primitiveScalar(layeredConfig.asString, 'key3', null)).to.throw('Unsupported scalar type');
    });
});
//# sourceMappingURL=layered-config.test.js.map