"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createDiscussion = createDiscussion;
exports.updateDiscussion = updateDiscussion;
exports.deleteDiscussion = deleteDiscussion;
const arcgis_rest_portal_1 = require("@esri/arcgis-rest-portal");
const slugs_1 = require("../items/slugs");
const ensureUniqueEntitySlug_1 = require("../items/_internal/ensureUniqueEntitySlug");
const settings_1 = require("./api/settings/settings");
const PropertyMapper_1 = require("../core/_internal/PropertyMapper");
const getPropertyMap_1 = require("./_internal/getPropertyMap");
const computeProps_1 = require("./_internal/computeProps");
const defaults_1 = require("./defaults");
const utils_1 = require("./utils");
const util_1 = require("../util");
const arcgis_1 = require("@terraformer/arcgis");
const createOrUpdateEntitySettings_1 = require("../core/_internal/createOrUpdateEntitySettings");
const createModel_1 = require("../models/createModel");
const getModel_1 = require("../models/getModel");
const updateModel_1 = require("../models/updateModel");
/**
 * @private
 * Create a new Hub Discussion item
 *
 * Minimal properties are name and orgUrlKey
 *
 * @param partialDiscussion a partial discussion
 * @param requestOptions user request options
 * @returns promise that resolves a IHubDiscussion
 */
async function createDiscussion(partialDiscussion, requestOptions) {
    // merge incoming with the default
    // this expansion solves the typing somehow
    const discussion = Object.assign(Object.assign({}, defaults_1.DEFAULT_DISCUSSION), partialDiscussion);
    // ensure orgUrlKey is set and downcased
    discussion.orgUrlKey = discussion.orgUrlKey.toLowerCase();
    // Create a slug from the title if one is not passed in
    if (!discussion.slug) {
        discussion.slug = (0, slugs_1.constructSlug)(discussion.name, discussion.orgUrlKey);
    }
    // Ensure slug is unique
    await (0, ensureUniqueEntitySlug_1.ensureUniqueEntitySlug)(discussion, requestOptions);
    discussion.typeKeywords = (0, utils_1.setDiscussableKeyword)(discussion.typeKeywords, discussion.isDiscussable);
    // Map discussion object onto a default discussion Model
    const mapper = new PropertyMapper_1.PropertyMapper((0, getPropertyMap_1.getPropertyMap)());
    // create model from object, using the default model as a starting point
    let model = mapper.entityToStore(discussion, (0, util_1.cloneObject)(defaults_1.DEFAULT_DISCUSSION_MODEL));
    // create the item
    model = await (0, createModel_1.createModel)(model, requestOptions);
    const newDiscussion = mapper.storeToEntity(model, {});
    // create the entity settings
    const entitySettings = await (0, createOrUpdateEntitySettings_1.createOrUpdateEntitySettings)(newDiscussion, requestOptions);
    newDiscussion.entitySettingsId = entitySettings.id;
    newDiscussion.discussionSettings = entitySettings.settings.discussions;
    return newDiscussion;
}
/**
 * @private
 * Update a Hub Discussion
 * @param discussion the discussion to update
 * @param requestOptions user request options
 * @returns promise that resolves a IHubDiscussion
 */
async function updateDiscussion(discussion, requestOptions) {
    var _a;
    // verify that the slug is unique, excluding the current discussion
    await (0, ensureUniqueEntitySlug_1.ensureUniqueEntitySlug)(discussion, requestOptions);
    discussion.typeKeywords = (0, utils_1.setDiscussableKeyword)(discussion.typeKeywords, discussion.isDiscussable);
    // get the backing item & data
    const model = await (0, getModel_1.getModel)(discussion.id, requestOptions);
    // create the PropertyMapper
    const mapper = new PropertyMapper_1.PropertyMapper((0, getPropertyMap_1.getPropertyMap)());
    // Note: Although we are fetching the model, and applying changes onto it,
    // we are not attempting to handle "concurrent edit" conflict resolution
    // but this is where we would apply that sort of logic
    const modelToUpdate = mapper.entityToStore(discussion, model);
    // update the backing item
    const updatedModel = await (0, updateModel_1.updateModel)(modelToUpdate, requestOptions);
    // now map back into a discussion and return that
    const updatedDiscussion = (0, computeProps_1.computeProps)(model, mapper.storeToEntity(updatedModel, discussion), requestOptions);
    // persist location geometries to discussion settings as Polygon[]
    let allowedLocations;
    try {
        allowedLocations =
            ((_a = updatedDiscussion.location.geometries) === null || _a === void 0 ? void 0 : _a.map((geometry) => (0, arcgis_1.arcgisToGeoJSON)(geometry))) || null;
    }
    catch (e) {
        allowedLocations = null;
        /* tslint:disable no-console */
        console.warn("Esri JSON conversion failed", e);
    }
    // create or update entity settings
    const entitySettings = await (0, createOrUpdateEntitySettings_1.createOrUpdateEntitySettings)(updatedDiscussion, requestOptions, allowedLocations);
    updatedDiscussion.entitySettingsId = entitySettings.id;
    updatedDiscussion.discussionSettings = entitySettings.settings.discussions;
    return updatedDiscussion;
}
/**
 * @private
 * Remove a Hub Discussion
 * @param id the discussion item id
 * @param requestOptions request options
 * @returns a promise
 */
async function deleteDiscussion(id, requestOptions) {
    const ro = Object.assign(Object.assign({}, requestOptions), { id });
    try {
        await (0, settings_1.removeSettingV2)(Object.assign({ id }, requestOptions));
    }
    catch (_e) {
        // suppress error
    }
    await (0, arcgis_rest_portal_1.removeItem)(ro);
    return;
}
//# sourceMappingURL=edit.js.map