"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Comment = void 0;
const utils_1 = require("../../utils");
const tag_1 = require("./tag");
const COPIED_TAGS = ["remarks"];
/**
 * A model that represents a comment.
 *
 * Instances of this model are created by the CommentPlugin. You can retrieve comments
 * through the {@link DeclarationReflection.comment} property.
 */
class Comment {
    /**
     * Creates a new Comment instance.
     */
    constructor(shortText, text) {
        /**
         * All associated tags.
         */
        this.tags = [];
        this.shortText = shortText || "";
        this.text = text || "";
    }
    /**
     * Has this comment a visible component?
     *
     * @returns TRUE when this comment has a visible component.
     */
    hasVisibleComponent() {
        return !!this.shortText || !!this.text || this.tags.length > 0;
    }
    /**
     * Test whether this comment contains a tag with the given name.
     *
     * @param tagName  The name of the tag to look for.
     * @returns TRUE when this comment contains a tag with the given name, otherwise FALSE.
     */
    hasTag(tagName) {
        return this.tags.some((tag) => tag.tagName === tagName);
    }
    /**
     * Return the first tag with the given name.
     *
     * You can optionally pass a parameter name that should be searched to.
     *
     * @param tagName  The name of the tag to look for.
     * @param paramName  An optional parameter name to look for.
     * @returns The found tag or undefined.
     */
    getTag(tagName, paramName) {
        return this.tags.find((tag) => {
            return (tag.tagName === tagName &&
                (paramName === void 0 || tag.paramName === paramName));
        });
    }
    /**
     * Removes all tags with the given tag name from the comment.
     * @param tagName
     */
    removeTags(tagName) {
        (0, utils_1.removeIf)(this.tags, (tag) => tag.tagName === tagName);
    }
    /**
     * Copy the data of the given comment into this comment.
     *
     * `shortText`, `text`, `returns` and tags from `COPIED_TAGS` are copied;
     * other instance tags left unchanged.
     *
     * @param comment - Source comment to copy from
     */
    copyFrom(comment) {
        this.shortText = comment.shortText;
        this.text = comment.text;
        this.returns = comment.returns;
        const overrideTags = comment.tags
            .filter((tag) => COPIED_TAGS.includes(tag.tagName))
            .map((tag) => new tag_1.CommentTag(tag.tagName, tag.paramName, tag.text));
        this.tags.forEach((tag, index) => {
            const matchingTag = overrideTags.find((matchingOverride) => (matchingOverride === null || matchingOverride === void 0 ? void 0 : matchingOverride.tagName) === tag.tagName);
            if (matchingTag) {
                this.tags[index] = matchingTag;
                overrideTags.splice(overrideTags.indexOf(matchingTag), 1);
            }
        });
        this.tags = [...this.tags, ...overrideTags];
    }
}
exports.Comment = Comment;
