"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IccApplicationSettingsXApi = void 0;
/**
 * iCure Data Stack API Documentation
 * The iCure Data Stack Application API is the native interface to iCure. This version is obsolete, please use v2.
 *
 * OpenAPI spec version: v1
 *
 *
 * NOTE: This class is auto generated by the swagger code generator program.
 * https://github.com/swagger-api/swagger-codegen.git
 * Do not edit the class manually.
 */
const icc_api_1 = require("../icc-api");
const models = require("../icc-api/model/models");
const utils_1 = require("./utils");
const ShareMetadataBehaviour_1 = require("./crypto/ShareMetadataBehaviour");
const models_1 = require("../icc-api/model/models");
var AccessLevelEnum = models_1.SecureDelegation.AccessLevelEnum;
const AuthenticationProvider_1 = require("./auth/AuthenticationProvider");
class IccApplicationSettingsXApi extends icc_api_1.IccApplicationsettingsApi {
    get headers() {
        return super.headers.then((h) => this.crypto.accessControlKeysHeaders.addAccessControlKeysHeaders(h, utils_1.EntityWithDelegationTypeName.ApplicationSettings));
    }
    constructor(host, headers, crypto, dataOwnerApi, autofillAuthor, encryptedKeys = ['encryptedSettings'], authenticationProvider = new AuthenticationProvider_1.NoAuthenticationProvider(), fetchImpl = typeof window !== 'undefined'
        ? window.fetch
        : typeof self !== 'undefined'
            ? self.fetch
            : fetch) {
        super(host, headers, authenticationProvider, fetchImpl);
        this.autofillAuthor = autofillAuthor;
        this.crypto = crypto;
        this.dataOwnerApi = dataOwnerApi;
        this.encryptedFields = (0, utils_1.parseEncryptedFields)(encryptedKeys, 'ApplicationSettings.');
    }
    newInstance(user_1) {
        return __awaiter(this, arguments, void 0, function* (user, c = {}, options = {}) {
            var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
            const applicationSettings = Object.assign(Object.assign({}, (c !== null && c !== void 0 ? c : {})), { _type: 'org.taktik.icure.entities.ApplicationSettings', id: (_a = c === null || c === void 0 ? void 0 : c.id) !== null && _a !== void 0 ? _a : this.crypto.primitives.randomUuid(), created: (_b = c === null || c === void 0 ? void 0 : c.created) !== null && _b !== void 0 ? _b : new Date().getTime(), modified: (_c = c === null || c === void 0 ? void 0 : c.modified) !== null && _c !== void 0 ? _c : new Date().getTime(), responsible: (_d = c === null || c === void 0 ? void 0 : c.responsible) !== null && _d !== void 0 ? _d : (this.autofillAuthor ? this.dataOwnerApi.getDataOwnerIdOf(user) : undefined), author: (_e = c === null || c === void 0 ? void 0 : c.author) !== null && _e !== void 0 ? _e : (this.autofillAuthor ? user.id : undefined) });
            const ownerId = this.dataOwnerApi.getDataOwnerIdOf(user);
            if (ownerId !== (yield this.dataOwnerApi.getCurrentDataOwnerId()))
                throw new Error('Can only initialise entities as current data owner.');
            const extraDelegations = Object.assign(Object.assign({}, (options.ignoreAutoDelegations == true
                ? {}
                : Object.fromEntries([...((_g = (_f = user.autoDelegations) === null || _f === void 0 ? void 0 : _f.all) !== null && _g !== void 0 ? _g : []), ...((_j = (_h = user.autoDelegations) === null || _h === void 0 ? void 0 : _h.medicalInformation) !== null && _j !== void 0 ? _j : [])].map((d) => [d, AccessLevelEnum.WRITE])))), ((_k = options === null || options === void 0 ? void 0 : options.additionalDelegates) !== null && _k !== void 0 ? _k : {}));
            return new models.ApplicationSettings(yield this.crypto.xapi
                .entityWithInitialisedEncryptedMetadata(applicationSettings, utils_1.EntityWithDelegationTypeName.ApplicationSettings, undefined, [], true, extraDelegations, options.alternateRootDelegation)
                .then((x) => x.updatedEntity));
        });
    }
    hasWriteAccess(applicationSettings) {
        return __awaiter(this, void 0, void 0, function* () {
            return this.crypto.xapi.hasWriteAccess({ entity: applicationSettings, type: utils_1.EntityWithDelegationTypeName.ApplicationSettings });
        });
    }
    shareWith(delegateId_1, applicationSettings_1) {
        return __awaiter(this, arguments, void 0, function* (delegateId, applicationSettings, options = {}) {
            return this.shareWithMany(applicationSettings, { [delegateId]: options });
        });
    }
    shareWithMany(applicationSettings, delegates) {
        return __awaiter(this, void 0, void 0, function* () {
            return (yield this.tryShareWithMany(applicationSettings, delegates)).updatedEntityOrThrow;
        });
    }
    tryShareWithMany(applicationSettings, delegates) {
        return __awaiter(this, void 0, void 0, function* () {
            // All entities should have an encryption key.
            const entityWithEncryptionKey = yield this.crypto.xapi.ensureEncryptionKeysInitialised(applicationSettings, utils_1.EntityWithDelegationTypeName.ApplicationSettings);
            const updatedEntity = entityWithEncryptionKey
                ? yield this.updateApplicationSettingsWithUser(undefined, entityWithEncryptionKey)
                : applicationSettings;
            return this.crypto.xapi.simpleShareOrUpdateEncryptedEntityMetadata({
                entity: updatedEntity,
                type: utils_1.EntityWithDelegationTypeName.ApplicationSettings,
            }, Object.fromEntries(Object.entries(delegates).map(([delegateId, options]) => [
                delegateId,
                {
                    requestedPermissions: options.requestedPermissions,
                    shareEncryptionKeys: options.shareEncryptionKey,
                    shareOwningEntityIds: ShareMetadataBehaviour_1.ShareMetadataBehaviour.NEVER,
                    shareSecretIds: [],
                },
            ])), (x) => this.bulkShareApplicationSettings(x));
        });
    }
    getDataOwnersWithAccessTo(entity) {
        return this.crypto.delegationsDeAnonymization.getDataOwnersWithAccessTo({ entity, type: utils_1.EntityWithDelegationTypeName.ApplicationSettings });
    }
    getEncryptionKeysOf(entity) {
        return this.crypto.xapi.encryptionKeysOf({ entity, type: utils_1.EntityWithDelegationTypeName.ApplicationSettings }, undefined);
    }
    createDelegationDeAnonymizationMetadata(entity, delegates) {
        return this.crypto.delegationsDeAnonymization.createOrUpdateDeAnonymizationInfo({ entity, type: utils_1.EntityWithDelegationTypeName.ApplicationSettings }, delegates);
    }
    createApplicationSettings(body) {
        return __awaiter(this, void 0, void 0, function* () {
            throw new Error('Use withUser method');
        });
    }
    getApplicationSettings() {
        return __awaiter(this, void 0, void 0, function* () {
            throw new Error('Use withUser method');
        });
    }
    updateApplicationSettings(body) {
        return __awaiter(this, void 0, void 0, function* () {
            throw new Error('Use withUser method');
        });
    }
    createApplicationSettingsWithUser(user, body) {
        const _super = Object.create(null, {
            createApplicationSettings: { get: () => super.createApplicationSettings }
        });
        return __awaiter(this, void 0, void 0, function* () {
            if (body.securityMetadata == null)
                throw new Error('Application settings does not have initialized encryption metadata; initialize or use non-encrypted api');
            return _super.createApplicationSettings.call(this, (yield this.encrypt([body]))[0]);
        });
    }
    getApplicationSettingsWithUser(user) {
        const _super = Object.create(null, {
            getApplicationSettings: { get: () => super.getApplicationSettings }
        });
        return __awaiter(this, void 0, void 0, function* () {
            const retrieved = yield _super.getApplicationSettings.call(this);
            return (yield this.tryDecryptOrReturnOriginal(retrieved)).map((x) => x.entity);
        });
    }
    updateApplicationSettingsWithUser(user, body) {
        const _super = Object.create(null, {
            updateApplicationSettings: { get: () => super.updateApplicationSettings }
        });
        return __awaiter(this, void 0, void 0, function* () {
            if (body.securityMetadata == null)
                throw new Error('Application settings does not have initialized encryption metadata; initialize or use non-encrypted api');
            return _super.updateApplicationSettings.call(this, (yield this.encrypt([body]))[0]);
        });
    }
    tryDecryptOrReturnOriginal(applicationSettings) {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.crypto.xapi.tryDecryptEntities(applicationSettings, utils_1.EntityWithDelegationTypeName.ApplicationSettings, (x) => new models.ApplicationSettings(x));
        });
    }
    encrypt(applicationSettings) {
        return this.crypto.xapi.tryEncryptEntities(applicationSettings, utils_1.EntityWithDelegationTypeName.ApplicationSettings, this.encryptedFields, true, false, (x) => new models.ApplicationSettings(x));
    }
}
exports.IccApplicationSettingsXApi = IccApplicationSettingsXApi;
//# sourceMappingURL=icc-application-settings-x-api.js.map