import { __esDecorate, __runInitializers } from "tslib";
import { html, nothing } from 'lit';
import { property, state } from 'lit/decorators.js';
import { Kind as RequestAuthorizationKind, } from '@api-client/core/models/RequestAuthorization.js';
import { AmfNamespace } from '@api-client/core/amf/definitions/Namespace.js';
import * as InputCache from '../../../amf/lib/InputCache.js';
import { Authorization } from '../../authorization/ui/Authorization.js';
import { AmfParameters } from '../../../amf/lib/AmfParameters.js';
let AmfPassThrough = (() => {
    let _classSuper = Authorization;
    let _security_decorators;
    let _security_initializers = [];
    let _security_extraInitializers = [];
    let _schemeName_decorators;
    let _schemeName_initializers = [];
    let _schemeName_extraInitializers = [];
    return class AmfPassThrough extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _security_decorators = [property({ type: Object })];
            _schemeName_decorators = [state()];
            __esDecorate(this, null, _security_decorators, { kind: "accessor", name: "security", static: false, private: false, access: { has: obj => "security" in obj, get: obj => obj.security, set: (obj, value) => { obj.security = value; } }, metadata: _metadata }, _security_initializers, _security_extraInitializers);
            __esDecorate(this, null, _schemeName_decorators, { kind: "accessor", name: "schemeName", static: false, private: false, access: { has: obj => "schemeName" in obj, get: obj => obj.schemeName, set: (obj, value) => { obj.schemeName = value; } }, metadata: _metadata }, _schemeName_initializers, _schemeName_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #security_accessor_storage = __runInitializers(this, _security_initializers, void 0);
        /**
         * The in-memory key where the values are stored.
         */
        get security() { return this.#security_accessor_storage; }
        set security(value) { this.#security_accessor_storage = value; }
        amfParameters = __runInitializers(this, _security_extraInitializers);
        #schemeName_accessor_storage = __runInitializers(this, _schemeName_initializers, void 0);
        get schemeName() { return this.#schemeName_accessor_storage; }
        set schemeName(value) { this.#schemeName_accessor_storage = value; }
        constructor() {
            super();
            __runInitializers(this, _schemeName_extraInitializers);
            this.amfParameters = new AmfParameters(this);
            this.amfParameters.globalCache = true;
            this.amfParameters.addEventListener('render', () => this.requestUpdate());
            this.amfParameters.addEventListener('change', () => this.notifyChange());
            this.amfParameters.addEventListener('paramchange', () => this.handleParamChange());
        }
        willUpdate(cp) {
            if (cp.has('security')) {
                this.restoreValues();
            }
            super.willUpdate(cp);
        }
        handleParamChange() {
            const auth = this.ensureConfig();
            auth.config = this.serialize();
        }
        ensureConfig() {
            if (!this.authorization) {
                this.authorization = {
                    enabled: true,
                    kind: RequestAuthorizationKind,
                    type: 'pass through',
                    valid: false,
                    config: {},
                };
            }
            return this.authorization;
        }
        restoreValues() {
            const { security } = this;
            const auth = this.ensureConfig();
            const source = 'settings';
            const list = this.amfParameters.parametersValue;
            this.amfParameters.parametersValue = list.filter((item) => item.source !== source);
            if (!security || !security.types.includes(AmfNamespace.aml.vocabularies.security.ParametrizedSecurityScheme)) {
                return;
            }
            const { scheme } = security;
            if (!scheme) {
                return;
            }
            const { type } = scheme;
            if (!type || !type.startsWith('Pass Through')) {
                return;
            }
            const { headers, queryParameters, queryString } = scheme;
            this.appendToParams(headers, 'header', true);
            this.appendToParams(queryParameters, 'query', true);
            if (queryString && (!queryParameters || !queryParameters.length)) {
                this.appendQueryString(queryString);
            }
            this.schemeName = security.name || scheme.name;
            this.notifyChange();
            this.requestUpdate();
            auth.config = this.serialize();
        }
        appendQueryString(queryString) {
            const object = queryString;
            if (!object.properties || !object.properties.length) {
                return;
            }
            const list = object.properties.map((item) => {
                const { id, range, name, minCount = 0 } = item;
                return {
                    id,
                    binding: 'query',
                    schema: range,
                    name,
                    examples: [],
                    payloads: [],
                    types: [AmfNamespace.aml.vocabularies.apiContract.Parameter],
                    required: minCount > 0,
                    customDomainProperties: [],
                };
            });
            this.appendToParams(list, 'query', true);
        }
        /**
         * Appends a list of parameters to the list of rendered parameters.
         * @param list
         * @param source
         * @param clear When set it clears the previously set parameters
         */
        appendToParams(list, source, clear = false) {
            const { amfParameters } = this;
            let params = amfParameters.parametersValue;
            if (clear) {
                params = params.filter((p) => p.source !== source);
            }
            if (Array.isArray(list)) {
                list.forEach((param) => {
                    params.push({
                        paramId: param.id,
                        parameter: param,
                        binding: param.binding || '',
                        source,
                        schema: param.schema,
                        schemaId: param.schema && param.schema.id ? param.schema.id : undefined,
                    });
                });
            }
            this.amfParameters.parametersValue = params;
        }
        /**
         * Updates, if applicable, query parameter value.
         *
         * This does nothing if the query parameter has not been defined for the current
         * scheme.
         *
         * @param name The name of the changed parameter
         * @param newValue A value to apply. May be empty but must be defined.
         */
        updateQueryParameter(name, newValue) {
            const list = this.amfParameters.parametersValue;
            const param = list.find((i) => i.binding === 'query' && i.parameter.name === name);
            if (param) {
                InputCache.set(this, param.paramId, newValue, true);
                this.requestUpdate();
            }
        }
        /**
         * Updates, if applicable, header value.
         * This is supported for RAML custom scheme and Pass Through
         * that operates on headers model which is only an internal model.
         *
         * This does nothing if the header has not been defined for current
         * scheme.
         *
         * @param name The name of the changed header
         * @param newValue A value to apply. May be empty but must be defined.
         */
        updateHeader(name, newValue) {
            const list = this.amfParameters.parametersValue;
            const param = list.find((i) => i.binding === 'header' && i.parameter.name === name);
            if (param) {
                InputCache.set(this, param.paramId, newValue, true);
                this.requestUpdate();
            }
        }
        serialize() {
            const params = this.amfParameters.parametersValue;
            const result = {};
            (params || []).forEach((param) => {
                if (!result[param.binding]) {
                    result[param.binding] = {};
                }
                let value = InputCache.get(this, param.paramId, true);
                if (value === '' || value === undefined) {
                    if (param.parameter.required === false) {
                        return;
                    }
                    value = '';
                }
                if (value === false && param.parameter.required === false) {
                    return;
                }
                if (value === null) {
                    value = '';
                }
                ;
                result[param.binding][param.parameter.name] = value;
            });
            return result;
        }
        checkValidity() {
            const { nilValues, parametersValue } = this.amfParameters;
            const hasInvalid = parametersValue.some((param) => {
                if (nilValues.includes(param.paramId)) {
                    return false;
                }
                const value = InputCache.get(this, param.paramId, true);
                if (!value && !param.parameter.required) {
                    return false;
                }
                return !value;
            });
            return !hasInvalid;
        }
        render() {
            return html ` ${this.renderHeader()} ${this.renderEditor()} `;
        }
        renderEditor() {
            return html `
      <form autocomplete="on" class="auth-form passthrough-auth">
        ${this.headersTemplate()} ${this.queryTemplate()}
      </form>
      ${this.renderAuthInfo()}
    `;
        }
        headersTemplate() {
            const headers = this.amfParameters.parametersValue.filter((item) => item.binding === 'header');
            if (!headers.length) {
                return nothing;
            }
            return html `
      <div class="section-title"><span class="label">Headers</span></div>
      ${headers.map((param) => this.amfParameters.parameterTemplate(param))}
    `;
        }
        queryTemplate() {
            const params = this.amfParameters.parametersValue.filter((item) => item.binding === 'query');
            if (!params.length) {
                return nothing;
            }
            return html `
      <div class="section-title"><span class="label">Query parameters</span></div>
      ${params.map((param) => this.amfParameters.parameterTemplate(param))}
    `;
        }
        renderHeader() {
            const { schemeName = 'Pass Through' } = this;
            return html `
      <div class="auth-header">
        <span class="auth-title">Scheme: ${schemeName}</span>
      </div>
    `;
        }
    };
})();
export default AmfPassThrough;
//# sourceMappingURL=AmfPassThrough.js.map