import { merge } from '../utils/object-utils.js';
import { addAll } from '../utils/set-utils.js';
export default class AbstractJDLOption {
    name;
    entityNames;
    excludedNames;
    annotations;
    constructor(args) {
        const merged = merge(defaults(), args);
        if (!merged.name) {
            throw new Error("The option's name must be passed to create an option.");
        }
        this.name = merged.name;
        this.entityNames = new Set(merged.entityNames);
        if (this.entityNames.size === 0) {
            this.entityNames.add('*');
        }
        this.annotations = merged.annotations;
        this.excludedNames = new Set(merged.excludedNames);
    }
    addEntityName(entityName) {
        if (!entityName) {
            throw new Error('An entity name has to be passed so as to be added to the option.');
        }
        if (this.excludedNames.has(entityName)) {
            return false;
        }
        if (this.entityNames.has('*')) {
            this.entityNames.delete('*');
        }
        return this.entityNames.add(entityName);
    }
    addEntitiesFromAnotherOption(option) {
        if (!option) {
            return false;
        }
        addAll(this.entityNames, Array.from(option.entityNames.values()));
        addAll(this.excludedNames, Array.from(option.excludedNames.values()));
        return true;
    }
    excludeEntityName(entityName) {
        if (!entityName) {
            throw new Error('An entity name has to be passed so as to be excluded from the option.');
        }
        if (this.entityNames.has(entityName)) {
            return;
        }
        this.excludedNames.add(entityName);
    }
    getType() {
        throw new Error('Unsupported operation');
    }
    setEntityNames(newEntityNames) {
        this.entityNames = new Set(newEntityNames);
    }
    resolveEntityNames(entityNames) {
        if (!entityNames) {
            throw new Error("Entity names have to be passed to resolve the option's entities.");
        }
        const resolvedEntityNames = this.entityNames.has('*') ? new Set(entityNames) : this.entityNames;
        this.excludedNames.forEach(excludedEntityName => {
            resolvedEntityNames.delete(excludedEntityName);
        });
        return resolvedEntityNames;
    }
}
function defaults() {
    return {
        entityNames: new Set(['*']),
        excludedNames: new Set(),
    };
}
