"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.CdmAttributeGroupDefinition = void 0;
const internal_1 = require("../internal");
class CdmAttributeGroupDefinition extends internal_1.CdmObjectDefinitionBase {
    constructor(ctx, attributeGroupName) {
        super(ctx);
        this.TAG = CdmAttributeGroupDefinition.name;
        // let bodyCode = () =>
        {
            this.objectType = internal_1.cdmObjectType.attributeGroupDef;
            this.attributeGroupName = attributeGroupName;
            this.members = new internal_1.CdmCollection(this.ctx, this, internal_1.cdmObjectType.typeAttributeDef);
        }
        // return p.measure(bodyCode);
    }
    static get objectType() {
        return internal_1.cdmObjectType.attributeGroupDef;
    }
    getObjectType() {
        // let bodyCode = () =>
        {
            return internal_1.cdmObjectType.attributeGroupDef;
        }
        // return p.measure(bodyCode);
    }
    isDerivedFrom(base, resOpt) {
        // let bodyCode = () =>
        {
            return false;
        }
        // return p.measure(bodyCode);
    }
    copy(resOpt, host) {
        // let bodyCode = () =>
        {
            if (!resOpt) {
                resOpt = new internal_1.resolveOptions(this, this.ctx.corpus.defaultResolutionDirectives);
            }
            let copy;
            if (!host) {
                copy = new CdmAttributeGroupDefinition(this.ctx, this.attributeGroupName);
            }
            else {
                copy = host;
                copy.attributeGroupName = this.attributeGroupName;
                copy.members.clear();
            }
            copy.attributeContext = this.attributeContext ? this.attributeContext.copy(resOpt) : undefined;
            for (const att of this.members) {
                copy.members.push(att.copy(resOpt));
            }
            this.copyDef(resOpt, copy);
            return copy;
        }
        // return p.measure(bodyCode);
    }
    validate() {
        // let bodyCode = () =>
        {
            if (!this.attributeGroupName) {
                let missingFields = ['attributeGroupName'];
                internal_1.Logger.error(this.ctx, this.TAG, this.validate.name, this.atCorpusPath, internal_1.cdmLogCode.ErrValdnIntegrityCheckFailure, missingFields.map((s) => `'${s}'`).join(', '), this.atCorpusPath);
                return false;
            }
            return true;
        }
        // return p.measure(bodyCode);
    }
    getName() {
        // let bodyCode = () =>
        {
            return this.attributeGroupName;
        }
        // return p.measure(bodyCode);
    }
    /**
     * @internal
     */
    getMembersAttributeDefs() {
        // let bodyCode = () =>
        {
            return this.members;
        }
        // return p.measure(bodyCode);
    }
    /**
     * @internal
     */
    addAttributeDef(attDef) {
        // let bodyCode = () =>
        {
            this.members.push(attDef);
            return attDef;
        }
        // return p.measure(bodyCode);
    }
    visit(pathFrom, preChildren, postChildren) {
        // let bodyCode = () =>
        {
            const path = this.fetchDeclaredPath(pathFrom);
            if (preChildren && preChildren(this, path)) {
                return false;
            }
            if (this.attributeContext) {
                this.attributeContext.owner = this;
                if (this.attributeContext.visit(`${path}/attributeContext/`, preChildren, postChildren)) {
                    return true;
                }
            }
            if (this.members) {
                if (this.members.visitArray(`${path}/members/`, preChildren, postChildren)) {
                    return true;
                }
            }
            if (this.visitDef(path, preChildren, postChildren)) {
                return true;
            }
            if (postChildren && postChildren(this, path)) {
                return true;
            }
            return false;
        }
        // return p.measure(bodyCode);
    }
    /**
     * @internal
     */
    constructResolvedAttributes(resOpt, under) {
        // let bodyCode = () =>
        {
            const rasb = new internal_1.ResolvedAttributeSetBuilder();
            const allUnder = under;
            if (under) {
                const acpAttGrp = {
                    under: under,
                    type: internal_1.cdmAttributeContextType.attributeGroup,
                    name: this.getName(),
                    regarding: this,
                    includeTraits: false
                };
                under = rasb.ras.createAttributeContext(resOpt, acpAttGrp);
            }
            if (this.members) {
                for (const att of this.members) {
                    let acpAtt;
                    if (under) {
                        acpAtt = {
                            under: under,
                            type: internal_1.cdmAttributeContextType.attributeDefinition,
                            name: att.fetchObjectDefinitionName(),
                            regarding: att,
                            includeTraits: false
                        };
                    }
                    const rasFromAtt = att.fetchResolvedAttributes(resOpt, acpAtt);
                    // before we just merge, need to handle the case of 'attribute restatement' AKA an entity with an attribute having the same name as an attribute
                    // from a base entity. thing might come out with different names, if they do, then any attributes owned by a similar named attribute before
                    // that didn't just pop out of that same named attribute now need to go away.
                    // mark any attributes formerly from this named attribute that don't show again as orphans
                    rasb.ras.markOrphansForRemoval(att.fetchObjectDefinitionName(), rasFromAtt);
                    // now merge
                    rasb.mergeAttributes(rasFromAtt);
                }
            }
            // context must be the one expected from the caller's pov.
            rasb.ras.setAttributeContext(allUnder);
            // things that need to go away
            rasb.removeRequestedAtts();
            return rasb;
        }
        // return p.measure(bodyCode);
    }
    /**
     * @deprecated
     * For internal use only.
     */
    fetchResolvedEntityReference(resOpt) {
        // let bodyCode = () =>
        {
            const rers = new internal_1.ResolvedEntityReferenceSet(resOpt);
            const l = this.members.length;
            for (let i = 0; i < l; i++) {
                rers.add(this.members.allItems[i].fetchResolvedEntityReference(resOpt));
            }
            return rers;
        }
        // return p.measure(bodyCode);
    }
    /**
     * @internal
     */
    constructResolvedTraits(rtsb, resOpt) {
        // let bodyCode = () =>
        {
            // get only the elevated traits from attributes first, then add in all traits from this definition
            if (this.members) {
                let rtsElevated = new internal_1.ResolvedTraitSet(resOpt);
                for (const att of this.members) {
                    const rtsAtt = att.fetchResolvedTraits(resOpt);
                    if (rtsAtt && rtsAtt.hasElevated) {
                        rtsElevated = rtsElevated.mergeSet(rtsAtt, true);
                    }
                }
                rtsb.mergeTraits(rtsElevated);
            }
            this.constructResolvedTraitsDef(undefined, rtsb, resOpt);
        }
        // return p.measure(bodyCode);
    }
}
exports.CdmAttributeGroupDefinition = CdmAttributeGroupDefinition;
//# sourceMappingURL=CdmAttributeGroupDefinition.js.map