"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.upsertLayoutResource = upsertLayoutResource;
const arcgis_rest_portal_1 = require("@esri/arcgis-rest-portal");
const HubError_1 = require("../HubError");
const object_to_json_blob_1 = require("../resources/object-to-json-blob");
const string_to_blob_1 = require("../resources/string-to-blob");
const removeResource_1 = require("../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>}
 */
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 = (0, object_to_json_blob_1.objectToJsonBlob)(resource);
        }
        if (extension === "txt") {
            resourceToUpload = (0, string_to_blob_1.stringToBlob)(resource);
        }
        // Add item resource
        // we do not check for existence first, because
        // our resource names are unique (timestamped)
        const response = await (0, arcgis_rest_portal_1.addItemResource)(Object.assign({ id,
            owner, resource: resourceToUpload, name: resourceName, prefix }, ro));
        // if err throw
        if (!response.success) {
            throw new HubError_1.default("Add Item Resource", `Error adding resource ${name} to item ${id}.`);
        }
        // then delete the old one if it exists
        const resources = await (0, arcgis_rest_portal_1.getItemResources)(id, ro);
        const foundResource = resources.resources.find((res) => {
            return (res.resource.startsWith(`${prefix}/${name}`) &&
                res.resource !== `${prefix}/${resourceName}`);
        });
        if (foundResource) {
            await (0, removeResource_1.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_1.default("Add Item Resource", err.message, err);
        }
        else {
            throw new HubError_1.default("Add Item Resource", `Error adding resource ${name} to item ${id}.`);
        }
    }
}
//# sourceMappingURL=upsertLayoutResource.js.map