import { addItemResource, getItemResources } from "@esri/arcgis-rest-portal";
import HubError from "../HubError";
import { objectToJsonBlob } from "../resources/object-to-json-blob";
import { stringToBlob } from "../resources/string-to-blob";
import { removeResource } from "../resources/removeResource";
/**
 * Given an item, and owner, Search for if the resource exists
 * and if does, update it, otherwise add it. Returns a url for the item.
 *
 * Note that layout resources are typically stored with
 * - a "layout/" prefix (so we can find them)
 * - a name that starts with the cardId
 * - and a -{timestamp} suffix (to bust the cache)
 * thus 'update' is not really an update, it is:
 * - upload the new one
 * - then find the old one (which has a different suffix) and delete it.
 *
 * this is why we cannot simply use upsertResource
 
 *
 * @export
 * @param {string} id
 * @param {string} owner
 * @param {*} resource
 * @param {string} name
 * @param {string} extension
 * @param {IUserRequestOptions} ro
 * @return {*}  {Promise<string>}
 */
export async function upsertLayoutResource(id, owner, resource, name, extension, ro) {
    try {
        const prefix = "layout";
        // construct resource name
        // the key is of the form <nodeId>-image-card
        // we also append a unique timestamp to avoid caching issues
        const resourceName = `${name}-${Date.now()}.${extension}`;
        // JSON and text resources have....odd things happen
        // to them when they are added as resources and NOT
        // converted to blobs. Thus we convert them to blobs
        let resourceToUpload = resource;
        if (extension === "json") {
            resourceToUpload = objectToJsonBlob(resource);
        }
        if (extension === "txt") {
            resourceToUpload = stringToBlob(resource);
        }
        // Add item resource
        // we do not check for existence first, because
        // our resource names are unique (timestamped)
        const response = await addItemResource(Object.assign({ id,
            owner, resource: resourceToUpload, name: resourceName, prefix }, ro));
        // if err throw
        if (!response.success) {
            throw new HubError("Add Item Resource", `Error adding resource ${name} to item ${id}.`);
        }
        // then delete the old one if it exists
        const resources = await getItemResources(id, ro);
        const foundResource = resources.resources.find((res) => {
            return (res.resource.startsWith(`${prefix}/${name}`) &&
                res.resource !== `${prefix}/${resourceName}`);
        });
        if (foundResource) {
            await removeResource(id, foundResource.resource, owner, ro);
        }
        // return url
        // resourceUrl://:id/:prefix/:filename
        return `resourceUrl://${id}/${prefix}/${resourceName}`;
    }
    catch (err) {
        if (err instanceof Error) {
            throw new HubError("Add Item Resource", err.message, err);
        }
        else {
            throw new HubError("Add Item Resource", `Error adding resource ${name} to item ${id}.`);
        }
    }
}
//# sourceMappingURL=upsertLayoutResource.js.map