import { cloneObject } from "../util";
import { buildDefaultChannel } from "./_internal/buildDefaultChannel";
import { fetchHubChannel } from "./fetch";
import { createHubChannel, deleteHubChannel, updateHubChannel } from "./edit";
import { getEditorConfig } from "../core/schemas/getEditorConfig";
import { transformEntityToEditor } from "./_internal/transformEntityToEditor";
import { transformEditorToEntity } from "./_internal/transformEditorToEntity";
export class HubChannel {
    constructor(entity, context) {
        this.isDestroyed = false;
        this.context = context;
        this.entity = entity;
    }
    /**
     * Create an instance from an IHubChannel object
     * @param json - JSON object to create a HubChannel from
     * @param context - ArcGIS context
     * @returns a HubChannel instance
     */
    static fromJson(json, context) {
        const pojo = this.applyDefaults(json, context);
        return new HubChannel(pojo, context);
    }
    /**
     * Create a new HubChannel, returning a HubChannel instance.
     * Note: This does not persist the Channel into the backing store
     * @param partialChannel A partial IHubChannel object
     * @param context ArcGIS Context
     * @returns a HubChannel instance
     */
    static async create(partialChannel, context, save = false) {
        const pojo = this.applyDefaults(partialChannel, context);
        const instance = HubChannel.fromJson(pojo, context);
        if (save) {
            await instance.save();
        }
        return instance;
    }
    /**
     * Fetch a Channel from the backing store and return a HubChannel instance.
     * @param identifier - Identifier of the channel to load
     * @param context - An IArcGISContext object
     * @returns a HubChannel instance
     */
    static async fetch(identifier, context) {
        try {
            const entity = await fetchHubChannel(identifier, context);
            return HubChannel.fromJson(entity, context);
        }
        catch (_e) {
            // TODO: any specific error handling? see HubProject fetch...
            throw new Error("Channel not found.");
        }
    }
    /**
     * Given a partial channel, apply defaults to it to ensure that a baseline of properties are set
     * @param partialChannel A partial IHubChannel object
     * @param context - ArcGIS Context
     * @returns an IHubChannel object
     */
    static applyDefaults(partialChannel, context) {
        const pojo = Object.assign(Object.assign({}, buildDefaultChannel(context.currentUser.orgId)), partialChannel);
        return pojo;
    }
    /**
     * Can the current user edit the channel?
     * @returns boolean
     */
    get canEdit() {
        return this.entity.canEdit;
    }
    /**
     * Can the current user delete the channel?
     * @returns boolean
     */
    get canDelete() {
        return this.entity.canDelete;
    }
    /**
     * The orgId of the channel
     * @returns the orgId of the channel
     */
    get orgId() {
        return this.entity.orgId;
    }
    /**
     * Return the backing entity as an object literal
     * @returns an IHubChannel
     */
    toJson() {
        if (this.isDestroyed) {
            throw new Error("HubChannel is already destroyed.");
        }
        return cloneObject(this.entity);
    }
    /**
     * Apply a new state to the instance
     * @param changes A partial IHubChannel object
     */
    update(changes) {
        if (this.isDestroyed) {
            throw new Error("HubChannel is already destroyed.");
        }
        this.entity = Object.assign(Object.assign({}, this.entity), changes);
    }
    /**
     * Save the HubChannel to the backing store.
     * @returns a promise
     */
    async save() {
        if (this.isDestroyed) {
            throw new Error("HubChannel is already destroyed.");
        }
        if (this.entity.id) {
            this.entity = await updateHubChannel(this.entity, this.context);
        }
        else {
            this.entity = await createHubChannel(this.entity, this.context);
        }
    }
    /**
     * Delete the HubChannel from the store
     * set a flag to indicate that it is destroyed
     * @returns a promise
     */
    async delete() {
        if (this.isDestroyed) {
            throw new Error("HubChannel is already destroyed.");
        }
        this.isDestroyed = true;
        await deleteHubChannel(this.entity.id, this.context);
    }
    /**
     * TODO
     * @param opts
     * @returns
     */
    convertToCardModel(_opts) {
        // TODO
        throw new Error("not implemented");
    }
    /**
     * Get a specifc editor config for the HubChannel entity.
     * @param i18nScope A string representing the i18n scope for translated strings
     * @param type One of the supported ChannelEditorType strings
     * @returns a promise that resolves a IEditorConfig object
     */
    async getEditorConfig(i18nScope, type) {
        return getEditorConfig(i18nScope, type, this.entity, this.context);
    }
    /**
     * Return the channel as an editor object
     * @param editorContext An IEntityEditorContext object
     * @param include An optional array of includes
     * @returns a promise that resolves an IHubChannelEditor object
     */
    async toEditor(_editorContext, _include) {
        return Promise.resolve(transformEntityToEditor(this.entity, this.context));
    }
    /**
     * Load the channel from the editor object
     * @param editor An IHubChannelEditor object
     * @returns a promise that resolves an IHubChannel
     */
    async fromEditor(editor) {
        this.entity = Object.assign(Object.assign({}, this.entity), transformEditorToEntity(editor));
        await this.save();
        return this.entity;
    }
}
//# sourceMappingURL=HubChannel.js.map