import { mcerror } from "./log";
/**
 * @remarks Reads a custom object stored on the entity or world. Automatically parses object as JSON.
 * @param subject The entity or world to read properties from.
 * @param propertyName The name of the property.
 * @returns The object stored as a property, may be undefined.
 * @example
 * ```typescript
 * const ownerName = readDynamicProperty<string>(entity, 'ownerName'); // Returns the string owner name or undefined if the property is absent.
 * ```
 */
export function readDynamicProperty(subject, propertyName) {
    const property = subject.getDynamicProperty(propertyName);
    if (property) {
        return JSON.parse(property);
    }
}
/**
 * @remarks Clears an existing property of the entity. Called automatically when overwriting an existing property.
 * @param subject The entity or world to clear the property on.
 * @param propertyName The property to clear.
 * @example
 * ```typescript
 * clearDynamicProperty(entity, 'ownerName'); // Clears the ownerName property from the entity.
 * ```
 */
export function clearDynamicProperty(subject, propertyName) {
    subject.setDynamicProperty(propertyName);
}
/**
 * @remarks Writes data to a property on the entity or world.
 * @param subject The entity or world to write the property to.
 * @param propertyName The property to write.
 * @param data The data to be written to the property. The data must be serializable with [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
 * @example
 * ```typescript
 * function tameEntity(player: SafetyCheckedPlayer, entity: SafetyCheckedEntity) {
 *  writeDynamicProperty(entity, player.name);
 * }
 * ```
 */
export function writeDynamicProperty(subject, propertyName, data) {
    subject.setDynamicProperty(propertyName, JSON.stringify(data));
}
/**
 * @deprecated This function has been deprecated in favor of {@link readDynamicProperty} due to tag size limits and performance issues.
 * @remarks Reads a custom object stored on the entity.
 * @param entity The entity who's properties to read.
 * @param propertyName The name of the property.
 * @returns The object stored as a property, may be undefined.
 */
export function readTagProperty(entity, propertyName) {
    try {
        const prop = entity.getTags().filter(tag => tag.startsWith('{')).map(tag => JSON.parse(tag)).filter(prop => prop[propertyName] !== undefined)[0];
        if (prop) {
            return prop[propertyName];
        }
    }
    catch (error) {
        mcerror(error);
    }
}
/**
 * @deprecated This function has been deprecated in favor of {@link clearDynamicProperty} due to tag size limits and performance issues.
 * @remarks Clears an existing property of the entity. Called automatically when overwriting an existing property.
 * @param entity The entity who's property to clear.
 * @param propertyName The property to clear.
 * @returns True if the property could be removed, False otherwise.
 */
export function clearTagProperty(entity, propertyName) {
    const tagData = readTagProperty(entity, propertyName);
    if (tagData) {
        return entity.removeTag(JSON.stringify({ [propertyName]: tagData }));
    }
    else {
        return false;
    }
}
/**
 * @deprecated This function has been deprecated in favor of {@link writeDynamicProperty} due to tag size limits and performance issues.
 * @remarks Writes data to a property on the entity.
 * @param entity The entity who's property will be written.
 * @param propertyName The property to write.
 * @param tagData The data to be written to the property. The data must be serializable with JSON.stringify.
 */
export function writeTagProperty(entity, propertyName, tagData) {
    clearTagProperty(entity, propertyName);
    entity.addTag(JSON.stringify({ [propertyName]: tagData }));
}
