import { __decorate } from "tslib";
import { html, nothing } from "lit";
import { property } from "lit/decorators.js";
import { RequestAuthorizationKind, AmfNamespace } from "@api-client/core/build/browser.js";
import { Authorization } from "../../authorization/ui/Authorization.js";
import { AmfParameters } from "../../../amf/lib/AmfParameters.js";
import * as InputCache from '../../../amf/lib/InputCache.js';
export default class AmfApiKey extends Authorization {
    constructor() {
        super();
        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: 'api key',
                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('Api Key')) {
            return;
        }
        const config = scheme.settings;
        if (!config) {
            return;
        }
        const { in: binding = '', id } = config;
        if (!InputCache.has(this, id, true)) {
            InputCache.set(this, id, '', true);
        }
        const params = this.amfParameters.parametersValue;
        params.push({
            binding,
            paramId: id,
            parameter: { ...config, binding },
            source: 'settings',
            schemaId: scheme.id,
            schema: scheme,
        });
        this.notifyChange();
        this.requestUpdate();
        auth.config = this.serialize();
    }
    /**
     * 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();
        }
    }
    /**
     * Updates, if applicable, cookie value.
     * This is supported in OAS' Api Key.
     *
     * This does nothing if the cookie has not been defined for current
     * scheme.
     *
     * @param name The name of the changed cookie
     * @param newValue A value to apply. May be empty but must be defined.
     */
    updateCookie(name, newValue) {
        const list = this.amfParameters.parametersValue;
        const param = list.find(i => i.binding === 'cookie' && i.parameter.name === name);
        if (param) {
            InputCache.set(this, param.paramId, newValue, true);
            this.requestUpdate();
        }
    }
    serialize() {
        const result = {};
        const params = this.amfParameters.parametersValue;
        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;
        return !parametersValue.some((param) => {
            if (nilValues.includes(param.paramId)) {
                return true;
            }
            const value = InputCache.get(this, param.paramId, true);
            return !value;
        });
    }
    render() {
        return html `
    ${this.renderHeader()}
    ${this.renderEditor()}
    `;
    }
    renderHeader() {
        return html `
    <div class="auth-header">
      <span class="auth-title">Scheme: Api Key</span>
    </div>
    `;
    }
    renderEditor() {
        return html `
    <form autocomplete="on" class="auth-form apikey-auth">
      ${this.headersTemplate()}
      ${this.queryTemplate()}
      ${this.cookieTemplate()}
    </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))}
    `;
    }
    cookieTemplate() {
        const params = this.amfParameters.parametersValue.filter(item => item.binding === 'cookie');
        if (!params.length) {
            return nothing;
        }
        return html `
    <div class="section-title"><span class="label">Cookies</span></div>
    ${params.map(param => this.amfParameters.parameterTemplate(param))}
    `;
    }
}
__decorate([
    property({ type: Object })
], AmfApiKey.prototype, "security", void 0);
//# sourceMappingURL=AmfApiKey.js.map