"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.CdmOperationAddAttributeGroup = void 0;
const internal_1 = require("../../internal");
/**
 * Class to handle AddAttributeGroup operations
 */
class CdmOperationAddAttributeGroup extends internal_1.CdmOperationBase {
    constructor(ctx) {
        super(ctx);
        this.TAG = CdmOperationAddAttributeGroup.name;
        this.objectType = internal_1.cdmObjectType.operationAddAttributeGroupDef;
        this.type = internal_1.cdmOperationType.addAttributeGroup;
    }
    /**
     * @inheritdoc
     */
    copy(resOpt, host) {
        if (!resOpt) {
            resOpt = new internal_1.resolveOptions(this, this.ctx.corpus.defaultResolutionDirectives);
        }
        const copy = !host ? new CdmOperationAddAttributeGroup(this.ctx) : host;
        copy.attributeGroupName = this.attributeGroupName;
        this.copyProj(resOpt, copy);
        return copy;
    }
    /**
     * @inheritdoc
     */
    getName() {
        return 'operationAddAttributeGroup';
    }
    /**
     * @inheritdoc
     */
    getObjectType() {
        return internal_1.cdmObjectType.operationAddAttributeGroupDef;
    }
    /**
     * @inheritdoc
     */
    validate() {
        const missingFields = [];
        if (!this.attributeGroupName) {
            missingFields.push('attributeGroupName');
        }
        if (missingFields.length > 0) {
            internal_1.Logger.error(this.ctx, this.TAG, this.validate.name, this.atCorpusPath, internal_1.cdmLogCode.ErrValdnIntegrityCheckFailure, this.atCorpusPath, missingFields.map((s) => `'${s}'`).join(', '));
            return false;
        }
        return true;
    }
    /**
     * @inheritdoc
     */
    visit(pathFrom, preChildren, postChildren) {
        const path = this.fetchDeclaredPath(pathFrom);
        if (preChildren && preChildren(this, path)) {
            return false;
        }
        if (postChildren && postChildren(this, path)) {
            return true;
        }
        return false;
    }
    /**
     * @inheritdoc
     * @internal
     */
    appendProjectionAttributeState(projCtx, projOutputSet, attrCtx) {
        // Create a new attribute context for the operation
        const attrCtxOpAddAttrGroupParam = {
            under: attrCtx,
            type: internal_1.cdmAttributeContextType.operationAddAttributeGroup,
            name: `operation/index${this.index}/${this.getName()}`
        };
        const attrCtxOpAddAttrGroup = internal_1.CdmAttributeContext.createChildUnder(projCtx.projectionDirective.resOpt, attrCtxOpAddAttrGroupParam);
        // Create a new attribute context for the attribute group we will create
        const attrCtxAttrGroupParam = {
            under: attrCtxOpAddAttrGroup,
            type: internal_1.cdmAttributeContextType.attributeDefinition,
            name: this.attributeGroupName
        };
        const attrCtxAttrGroup = internal_1.CdmAttributeContext.createChildUnder(projCtx.projectionDirective.resOpt, attrCtxAttrGroupParam);
        // Create a new resolve attribute set builder that will be used to combine all the attributes into one set
        const rasb = new internal_1.ResolvedAttributeSetBuilder();
        // Iterate through all the projection attribute states generated from the source's resolved attributes
        // Each projection attribute state contains a resolved attribute that it is corresponding to
        for (const currentPAS of projCtx.currentAttributeStateSet.states) {
            // Create a copy of the resolved attribute
            const resolvedAttribute = currentPAS.currentResolvedAttribute.copy();
            // Add the attribute to the resolved attribute set
            rasb.ras.merge(resolvedAttribute);
            // Add each attribute's attribute context to the resolved attribute set attribute context
            const attrParam = {
                under: attrCtxAttrGroup,
                type: internal_1.cdmAttributeContextType.attributeDefinition,
                name: resolvedAttribute.resolvedName
            };
            resolvedAttribute.attCtx = internal_1.CdmAttributeContext.createChildUnder(projCtx.projectionDirective.resOpt, attrParam);
            resolvedAttribute.attCtx.addLineage(currentPAS.currentResolvedAttribute.attCtx);
        }
        // Create a new resolved attribute that will hold the attribute set containing all the attributes
        const resAttrNew = new internal_1.ResolvedAttribute(projCtx.projectionDirective.resOpt, rasb.ras, this.attributeGroupName, attrCtxAttrGroup);
        // Create a new projection attribute state pointing to the resolved attribute set that represents the attribute group
        const newPAS = new internal_1.ProjectionAttributeState(this.ctx);
        newPAS.currentResolvedAttribute = resAttrNew;
        projOutputSet.add(newPAS);
        return projOutputSet;
    }
}
exports.CdmOperationAddAttributeGroup = CdmOperationAddAttributeGroup;
//# sourceMappingURL=CdmOperationAddAttributeGroup.js.map