import { __decorate } from "tslib";
/* eslint-disable class-methods-use-this */
import { html, nothing } from 'lit';
import { property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { Events as CoreEvents, HttpRequest, SecurityProcessor, RequestAuthorization, PayloadSerializer, RequestConfig, } from '@api-client/core/build/browser.js';
import { EventTypes } from '../../events/EventTypes.js';
import { Events } from '../../events/Events.js';
import ApiElement from '../ApiElement.js';
import { authTypeToLabel } from '../authorization/AuthLabels.js';
import '../../define/ui/ui-icon.js';
import '../../define/http/http-url-input.js';
import '../../define/http/http-url-params-form.js';
import '../../define/http/http-headers-form.js';
import '../../define/http/http-snippets.js';
import '../../define/http/http-body-editor.js';
import '../../define/http/http-assertions.js';
import '../../define/http/http-flows.js';
import '../../define/http/http-request-config.js';
import '../../define/ui/ui-dropdown-list.js';
import '../../define/ui/ui-list.js';
import '../../define/ui/ui-list-item.js';
import '../../define/ui/ui-button.js';
import '../../define/ui/ui-tabs.js';
import '../../define/ui/ui-tab.js';
import '../../define/ui/ui-divider.js';
import '../../define/ui/ui-dialog.js';
import '../../define/authorization/basic-authorization.js';
import '../../define/authorization/bearer-authorization.js';
import '../../define/authorization/ntlm-authorization.js';
import '../../define/authorization/apikey-authorization.js';
import '../../define/authorization/oauth2-authorization.js';
import '../../define/authorization/oidc-authorization.js';
import '../../define/authorization/cc-authorization.js';
export const HttpMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'CONNECT', 'OPTIONS', 'TRACE'];
export const NonPayloadMethods = ['GET', 'HEAD'];
/**
 * An element that renders an HTTP editor.
 *
 * @fires send - A custom event when the user requested to send the request. The detail object is the editor's request.
 * @fires abort - When the user requested to abort the ongoing request.
 * @fires authorizationchange - When authorization data change.
 * @fires uichange - When the UI model change.
 */
export default class RequestEditor extends ApiElement {
    /**
     * @returns True when the request cannot have the payload on the message.
     */
    get isPayload() {
        const { request } = this;
        if (!request || !request.method) {
            return false;
        }
        return !NonPayloadMethods.includes(request.method);
    }
    constructor() {
        super();
        /**
         * A promise set when reading payload from the `request` object.
         * It is resolved after the payload is read anf the `payload` property is set.
         */
        this.readingPayloadPromise = Promise.resolve();
        /**
         * A promise set when the payload is being written to the `request` object.
         * It is resolved after the `payload` is set on the request as a serializable object.
         */
        this.writingPayloadPromise = Promise.resolve();
        /**
         * A flag used to determine when the payload is being read for the synchronous code.
         */
        this.readingPayload = false;
        /**
         * The base request object.
         */
        this.request = new HttpRequest().toJSON();
        /**
         * When set the editor is in read only mode.
         */
        this.readOnly = false;
        /**
         * When set it ignores all `content-*` headers when the request method is `GET`.
         * When not set or `false` it renders a warning message.
         */
        this.ignoreContentOnGet = false;
        /**
         * When set the `content-` headers warning dialog is rendered.
         */
        this.contentHeadersDialogOpened = false;
        /**
         * To be set when the request is being transported.
         */
        this.loading = false;
        /**
         * An index of currently opened tab.
         * @default 0
         */
        this.selectedTab = 'parameters';
        /**
         * HTTP request configuration for the transport.
         */
        this.config = new RequestConfig().toJSON();
        this._awaitingOAuth2authorization = false;
        /**
         * This is set by the internal logic. When `ignoreContentOnGet` is set and the headers have `content-` headers
         * a dialog is rendered when trying to send the request. When the user chooses to ignore the warning this
         * flag makes sure that `send()` does not check headers.
         *
         * @todo(pawel): This should be done in the request logic module plugin.
         * Plugins can stop request indefinitely or cancel it.
         */
        this.ignoreValidationOnGet = false;
        this.config.enabled = false;
        this.handleInternalSend = this.handleInternalSend.bind(this);
    }
    connectedCallback() {
        super.connectedCallback();
        this.eventsTarget.addEventListener(EventTypes.Http.Request.send, this.handleInternalSend);
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        this.eventsTarget.addEventListener(EventTypes.Http.Request.send, this.handleInternalSend);
    }
    firstUpdated(changedProperties) {
        super.firstUpdated(changedProperties);
        this.computeSnippetsRequest();
    }
    willUpdate(changedProperties) {
        if (changedProperties.has('request')) {
            this.setupContentType();
            this.readingPayloadPromise = this.readPayload();
        }
        if (changedProperties.has('ui') && this.ui) {
            if (this.ui.selectedEditor) {
                this.selectedTab = this.ui.selectedEditor;
            }
        }
        super.willUpdate(changedProperties);
    }
    setupContentType(request = this.request) {
        if (!request) {
            this.contentType = undefined;
            return;
        }
        if (!request.headersModel) {
            this.contentType = undefined;
            return;
        }
        const item = request.headersModel.find(i => i.name.toLowerCase() === 'content-type');
        if (!item) {
            this.contentType = undefined;
            return;
        }
        this.contentType = item.value;
        this.setPayloadMimeOption(request, this.contentType);
    }
    async readPayload() {
        const { request } = this;
        if (!request || !request.payload) {
            this.payload = undefined;
            return;
        }
        this.readingPayload = true;
        try {
            this.payload = await PayloadSerializer.deserialize(request.payload);
        }
        catch (e) {
            this.payload = undefined;
        }
        finally {
            this.readingPayload = false;
        }
    }
    /**
     * Validates state of the URL.
     * @return True if the URL has a structure that looks like
     * an URL which means scheme + something
     */
    validateUrl() {
        const { shadowRoot } = this;
        if (!shadowRoot) {
            return true;
        }
        const panel = shadowRoot.querySelector('http-url-input');
        if (!panel) {
            return true;
        }
        return panel.checkValidity();
    }
    /**
     * Checks if current request requires calling `authorize()` on the OAuth2 method.
     *
     * @return This returns `true` only for valid OAuth 2 method that has no access token.
     */
    requiresAuthorization() {
        const { authorization = [] } = this;
        const oauth = authorization.find((method) => method.enabled && method.type === 'oauth 2');
        if (!oauth) {
            return false;
        }
        const authMethod = this.shadowRoot?.querySelector('oauth2-authorization');
        if (!authMethod) {
            return false;
        }
        const cnf = oauth.config;
        if (authMethod.checkValidity() && !cnf.accessToken) {
            return true;
        }
        return false;
    }
    /**
     * Validates headers for `Content-*` entries against current method.
     * @param request The request object
     * @return True if headers are invalid.
     */
    validateContentHeaders(request) {
        const method = request.method || 'get';
        if (method.toLowerCase() !== 'get') {
            return false;
        }
        const any = !!request.headersModel && request.headersModel.some(i => i.name.toLowerCase().startsWith('content-'));
        if (any) {
            return true;
        }
        return false;
    }
    /**
     * Serializes the current values to the `IHttpRequest`
     */
    async serialize() {
        if (!this.request) {
            const instance = new HttpRequest();
            return instance.toJSON();
        }
        await this.writingPayloadPromise;
        // make sure we copy everything.
        const instance = new HttpRequest(this.request);
        return instance.toJSON();
    }
    /**
     * Dispatches the send request event to the HTTP request engine.
     */
    async send() {
        if (this.loading || !this.request) {
            return;
        }
        if (!this.validateUrl()) {
            return;
        }
        if (this.requiresAuthorization()) {
            const authMethod = this.shadowRoot?.querySelector('oauth2-authorization');
            if (authMethod) {
                authMethod.authorize();
                this._awaitingOAuth2authorization = true;
            }
            return;
        }
        const request = await this.serialize();
        // store the URL in the history
        await Events.HttpClient.Model.UrlHistory.add(request.url, this);
        if (!this.ignoreValidationOnGet && this.validateContentHeaders(request)) {
            this.contentHeadersDialogOpened = true;
            return;
        }
        this.ignoreValidationOnGet = false;
        this.notifySend(request);
        CoreEvents.Telemetry.event({
            category: 'Request editor',
            action: 'Send request',
        }, this);
    }
    notifySend(request) {
        this.dispatchEvent(new CustomEvent('send', {
            detail: {
                request,
                authorization: this.authorization,
                config: this.config,
                assertions: this.assertions,
            },
        }));
    }
    /**
     * If the request does not exist it creates one.
     * @returns The request object.
     */
    getRequest() {
        if (!this.request) {
            const instance = new HttpRequest();
            this.request = instance.toJSON();
        }
        return this.request;
    }
    /**
     * Aborts the request
     */
    abort() {
        this.dispatchEvent(new Event('abort'));
    }
    handleInternalSend(e) {
        e.stopPropagation();
        this.send();
    }
    handleVerbSelection(e) {
        const target = e.detail.item;
        if (!target) {
            return;
        }
        const { verb } = target.dataset;
        if (verb) {
            this.selectVerb(verb);
        }
    }
    /**
     * @param verb The HTTP verb (operation, method)
     */
    selectVerb(verb) {
        const request = this.getRequest();
        request.method = verb;
        this.requestUpdate();
        this.notifyChange();
        this.notifyPropertyChanged('method', verb);
        if (!this.isPayload && this.selectedTab === 'payload') {
            this.selectedTab = 'headers';
        }
        CoreEvents.Telemetry.event({
            category: 'Request editor',
            action: 'Method selected',
            label: verb,
        }, this);
        this.computeSnippetsRequest();
    }
    /**
     * The handler for the URL editor change event
     */
    handlerUrlChange(e) {
        const panel = e.target;
        const { value } = panel;
        this.selectUrl(value);
    }
    /**
     * Commits the change in the URL.
     * @param value The new URL value
     */
    selectUrl(value) {
        const request = this.getRequest();
        request.url = value;
        this.requestUpdate();
        this.notifyChange();
        this.notifyPropertyChanged('url', value);
        this.computeSnippetsRequest();
    }
    handleTabSelect(e) {
        const info = e.detail;
        this.selectedTab = info.select;
        if (this.ui) {
            this.ui.selectedEditor = this.selectedTab;
            this.notifyPropertyChanged('ui', this.ui);
        }
        CoreEvents.Telemetry.event({
            category: 'Request editor',
            action: 'Editor switched',
            label: this.selectedTab,
        }, this);
    }
    handleParamsChange(e) {
        const input = e.target;
        this.selectUrl(input.value);
    }
    /**
     * The handler for the headers change event from the headers editor.
     */
    handleHeadersChange(e) {
        e.preventDefault();
        const editor = e.target;
        const { model } = editor;
        this.selectHeaders(model);
        if (!this.ui) {
            return;
        }
        // const { value, source } = node;
        if (!this.ui.headers) {
            this.ui.headers = {};
        }
        // this.ui.headers.source = source;
        this.notifyPropertyChanged('ui', this.ui);
    }
    selectHeaders(model) {
        const request = this.getRequest();
        request.headersModel = model;
        const ct = model.find(h => h.name.toLowerCase() === 'content-type');
        this.contentType = ct && ct.value;
        this.setPayloadMimeOption(request, this.contentType);
        this.requestUpdate();
        this.notifyChange();
        this.computeSnippetsRequest();
    }
    /**
     * The handler for the body editor change event
     */
    handleBody(e) {
        e.preventDefault();
        const node = e.target;
        const { value, model, selected, contentType } = node;
        this.writingPayloadPromise = this.updatePayload(value, contentType);
        this.computeSnippetsRequest();
        if (!this.ui) {
            return;
        }
        if (!this.ui.body) {
            this.ui.body = {};
        }
        this.ui.body.model = model;
        this.ui.body.selected = selected;
        this.notifyPropertyChanged('ui', this.ui);
    }
    async updatePayload(value, mime) {
        const serialized = await PayloadSerializer.serialize(value);
        const request = this.getRequest();
        request.payload = serialized;
        this.setPayloadMimeOption(request, mime);
        this.payload = value;
        this.requestUpdate();
        this.notifyChange();
        this.notifyPropertyChanged('payload', value);
    }
    /**
     * When `mime` is set it creates the `payloadOptions` property with the mime.
     * @param request The request to set the mime type
     * @param mime the mime type value
     */
    setPayloadMimeOption(request, mime) {
        if (mime) {
            if (!request.payloadOptions) {
                request.payloadOptions = {};
            }
            request.payloadOptions.mime = mime;
        }
    }
    handleFlows(e) {
        e.preventDefault();
        const node = e.target;
        this.selectFlows(node.model);
    }
    selectFlows(flows) {
        this.flows = flows;
        this.notifyChange();
    }
    handleAssertions(e) {
        e.preventDefault();
        const node = e.target;
        this.selectAssertions(node.model);
    }
    selectAssertions(assertions) {
        this.assertions = assertions;
        this.notifyChange();
    }
    handleConfig(e) {
        const node = e.target;
        this.selectRequestConfig(node.config);
    }
    selectRequestConfig(config) {
        this.config = config;
        this.notifyChange();
    }
    /**
     * Called to notify listeners about a particular property change
     *
     * @param type The property that changed. The resulting event type is the combination of this value and the `change` suffix.
     * @param value The value of the changed property
     */
    notifyPropertyChanged(type, value) {
        this.dispatchEvent(new CustomEvent(`${type}change`, {
            detail: {
                value
            }
        }));
    }
    handleContentWarningClose(e) {
        this.contentHeadersDialogOpened = false;
        if (e.detail.cancelled) {
            return;
        }
        this.ignoreValidationOnGet = true;
        this.send();
    }
    /**
     * When a request change this recomputes the values for code snippets.
     * These are different from the actual values in the request as
     * they contain authorization values applied to it.
     */
    async computeSnippetsRequest() {
        const serialized = await this.serialize();
        const { authorization = [] } = this;
        SecurityProcessor.applyAuthorization(serialized, [...authorization], { immutable: true });
        this.snippets = serialized;
    }
    /**
     * Adds a new authorization object to the request for the given type.
     *
     * @returns The created instance of the authorization.
     */
    addAuthorization(type) {
        const cnf = RequestAuthorization.fromTypedConfig(type, {}, false);
        cnf.enabled = true;
        if (!this.authorization) {
            this.authorization = [];
        }
        this.authorization.push(cnf.toJSON());
        this.notifyPropertyChanged('authorization', this.authorization);
        this.requestUpdate();
        return cnf;
    }
    /**
     * Updates authorization schema on the editor.
     * @param schema The new schema to replace the old one
     * @param isValid Whether the schema is valid.
     */
    updateAuthorization(schema, isValid) {
        const { authorization } = this;
        if (!authorization) {
            return;
        }
        const index = authorization.findIndex(i => i.type === schema.type);
        if (index === -1) {
            return;
        }
        // eslint-disable-next-line no-param-reassign
        schema.valid = isValid;
        authorization[index] = schema;
        this.notifyPropertyChanged('authorization', this.authorization);
    }
    /**
     * Removes authorization schema from the editor.
     * @param type The authorization type to remove.
     */
    removeAuthorization(type) {
        const { authorization } = this;
        if (!authorization) {
            return;
        }
        const index = authorization.findIndex(i => i.type === type);
        if (index === -1) {
            return;
        }
        authorization.splice(index, 1);
        this.notifyPropertyChanged('authorization', this.authorization);
        this.requestUpdate();
    }
    handleAuthAdd(e) {
        const target = e.detail.item;
        if (!target) {
            return;
        }
        const selected = target.dataset.type;
        if (!selected) {
            return;
        }
        this.addAuthorization(selected);
    }
    handleAuthChange(e) {
        const editor = e.target;
        const { authorization } = editor;
        this.updateAuthorization(authorization, editor.checkValidity());
    }
    handleAuthDelete(e) {
        const editor = e.target;
        const { authorization } = editor;
        if (!authorization) {
            return;
        }
        this.removeAuthorization(authorization.type);
    }
    render() {
        return html `
    ${this.renderUrlEditorArea()}
    <div class="surface2 editors">
      ${this.renderTabs()}
      ${this.renderCurrentEditor()}
    </div>
    ${this.renderHeadersDialog()}
    `;
    }
    /**
     * @returns The template for the top line with method selector, URL, and options.
     */
    renderUrlEditorArea() {
        return html `
    <div class="url-editor">
      <div class="url-meta">
        ${this.renderUrlMeta()}
      </div>
      ${this.renderSendButton()}
    </div>
    `;
    }
    renderUrlMeta() {
        return html `
    ${this.renderHttpMethodSelector()}
    ${this.renderUrlEditor()}
    `;
    }
    /**
     * @returns The template for the HTTP method selector
     */
    renderHttpMethodSelector() {
        const request = this.getRequest();
        const { method = 'GET' } = request;
        return html `
    <ui-dropdown-list
      verticalAlign="top"
      @select="${this.handleVerbSelection}"
      class="verb-dropdown"
      closeOnOutsideClick
    >
      <ui-button type="text">
        ${method}
        <ui-icon icon="arrowDropDown"></ui-icon>
      </ui-button>
      <ui-list slot="dropdown" role="menu">
        ${this.renderHttpVerbOptions()}
      </ui-list>
    </ui-dropdown-list>
    `;
    }
    /**
     * @returns The templates for each supported HTTP methods
     */
    renderHttpVerbOptions() {
        return HttpMethods.map((method) => html `
    <ui-list-item role="menuitem" image="icon" data-verb="${method}">
      <div slot="start" data-method="${method.toLocaleLowerCase()}" class="http-label"></div>
      ${method}
    </ui-list-item>
    `);
    }
    /**
     * @returns The template for the HTTP URL editor
     */
    renderUrlEditor() {
        const request = this.getRequest();
        const { url = '' } = request;
        const { eventsTarget } = this;
        return html `
    <div class="url-input">
      <http-url-input
        .value="${url}"
        .eventsTarget="${eventsTarget}"
        @change="${this.handlerUrlChange}"
      ></http-url-input>
    </div>
    `;
    }
    /**
     * @returns The template for the "send" or "abort" buttons.
     */
    renderSendButton() {
        if (this.loading) {
            return html `
      <ui-button type="filled" title="Abort the request" class="send-button" @click="${this.abort}">Abort</ui-button>
      `;
        }
        return html `
    <ui-button type="filled" title="Send the request" class="send-button" @click="${this.send}">Send</ui-button>
    `;
    }
    /**
     * @returns The template for the request editor tabs
     */
    renderTabs() {
        const { isPayload, selectedTab } = this;
        //  ui && ui.selectedEditor ||
        const selected = selectedTab;
        return html `
    <ui-tabs
      .selected="${selected}"
      @select="${this.handleTabSelect}"
      class="editor-tabs"
    >
      <ui-tab aria-controls="parameters" id="parameters-tab">Parameters</ui-tab>
      <ui-tab aria-controls="headers" id="headers-tab">Headers</ui-tab>
      <ui-tab ?hidden="${!isPayload}" aria-controls="payload" id="payload-tab">Body</ui-tab>
      <ui-tab aria-controls="authorization" id="authorization-tab">Authorization</ui-tab>
      <ui-tab aria-controls="flows" id="flows-tab">Flows</ui-tab>
      <ui-tab aria-controls="assertions" id="assertions-tab">Assertions</ui-tab>
      <ui-tab aria-controls="config" id="config-tab">Config</ui-tab>
      <ui-tab aria-controls="code-snippets" id="code-snippets-tab">Code snippets</ui-tab>
    </ui-tabs>`;
    }
    /**
     * @returns The template for the current editor
     */
    renderCurrentEditor() {
        const { selectedTab, isPayload } = this;
        const parametersVisible = selectedTab === 'parameters';
        const headersVisible = selectedTab === 'headers';
        const bodyVisible = isPayload && selectedTab === 'payload';
        const authVisible = selectedTab === 'authorization';
        const codeVisible = selectedTab === 'code-snippets';
        const assertionsVisible = selectedTab === 'assertions';
        const configVisible = selectedTab === 'config';
        const flowsVisible = selectedTab === 'flows';
        return html `
    <div class="panel">
      ${this.renderParameters(parametersVisible)}
    ${this.renderHeaders(headersVisible)}
    ${this.renderBody(bodyVisible)}
    ${this.renderAuthorization(authVisible)}
    ${this.renderHttpFlows(flowsVisible)}
    ${this.renderAssertions(assertionsVisible)}
    ${this.renderRequestConfig(configVisible)}
    ${this.renderSnippets(codeVisible)}
    </div>
    `;
    }
    renderParameters(visible) {
        const request = this.getRequest();
        const { eventsTarget, readOnly, } = this;
        return html `
    <http-url-params-form
      id="parameters"
      aria-describedby="parameters-tab"
      role="tabpanel"
      ?hidden="${!visible}"
      .value="${request.url || ''}"
      .eventsTarget="${eventsTarget}"
      ?readOnly="${readOnly}"
      @change="${this.handleParamsChange}"
    ></http-url-params-form>
    `;
    }
    /**
     * @param visible Whether the panel should not be hidden
     * @returns The template for the headers editor
     */
    renderHeaders(visible) {
        const request = this.getRequest();
        const { eventsTarget, readOnly, } = this;
        return html `
    <http-headers-form
      id="headers"
      aria-describedby="headers-tab"
      role="tabpanel"
      .eventsTarget="${eventsTarget}"
      .model="${request.headersModel || []}"
      ?hidden="${!visible}"
      @change="${this.handleHeadersChange}"
      ?readonly="${readOnly}"
    ></http-headers-form>`;
    }
    /**
     * @param visible Whether the panel should not be hidden
     * @returns The template for the body editor
     */
    renderBody(visible) {
        const { payload, readOnly, contentType, ui, readingPayload } = this;
        if (readingPayload) {
            return html `<p class="loading-body" id="payload">Preparing the editor...</p>`;
        }
        const body = ui && ui.body;
        const selected = body && body.selected;
        const model = body && body.model;
        return html `
    <http-body-editor
      id="payload"
      aria-describedby="payload-tab"
      role="tabpanel"
      ?hidden="${!visible}"
      ?readOnly="${readOnly}"
      .contentType="${contentType}"
      .model="${model}"
      .value="${!model && payload || undefined}"
      selected="${ifDefined(selected)}"
      @change="${this.handleBody}"
      @select="${this.handleBody}"
    ></http-body-editor>
    `;
    }
    /**
     * @param visible Whether the panel should not be hidden
     * @returns The template for the authorization editor
     */
    renderAuthorization(visible) {
        const { authorization } = this;
        return html `
    <section ?hidden="${!visible}" id="authorization" aria-describedby="authorization-tab" role="tabpanel">
      ${this.renderAuthorizationActions(authorization)}
      ${this.renderAuthorizationList(authorization)}
    </section>
    `;
    }
    renderAuthorizationActions(current = []) {
        const all = ['basic', 'oauth 2', 'open id', 'bearer', 'api key', 'ntlm', 'client certificate'];
        const toRender = all.filter(type => !current.some(i => i.type === type));
        return html `
    <ui-dropdown-list
      verticalAlign="top"
      @select="${this.handleAuthAdd}"
      class="auth-dropdown"
      closeOnOutsideClick
    >
      <ui-button 
        type="tonal" 
        title="Add authorization option" 
        aria-label="Opens a menu to select authorization option"
        ?disabled="${!toRender.length}"
      >
        <ui-icon icon="arrowDropDown" slot="icon" role="presentation"></ui-icon>
        Add
      </ui-button>
      <ui-list slot="dropdown" role="menu">
        ${this.renderAuthorizationOptions(toRender)}
      </ui-list>
    </ui-dropdown-list>
    `;
    }
    renderAuthorizationOptions(available) {
        return html `
    ${available.map(type => html `
    <ui-list-item role="menuitem" data-type="${type}">
      ${authTypeToLabel(type)}
    </ui-list-item>
    `)}
    `;
    }
    renderAuthorizationList(authorization = []) {
        if (!Array.isArray(authorization) || !authorization.length) {
            return [this.renderEmptyAuthorization()];
        }
        return authorization.map((item, index) => {
            let content;
            switch (item.type) {
                case 'basic':
                    content = this.renderBasicAuthorization(item);
                    break;
                case 'bearer':
                    content = this.renderBearerAuthorization(item);
                    break;
                case 'ntlm':
                    content = this.renderNtlmAuthorization(item);
                    break;
                case 'oauth 2':
                    content = this.renderOauthAuthorization(item);
                    break;
                case 'open id':
                    content = this.renderOidcAuthorization(item);
                    break;
                case 'client certificate':
                    content = this.renderCCAuthorization(item);
                    break;
                case 'api key':
                    content = this.renderApiKeyAuthorization(item);
                    break;
                default:
            }
            if (content) {
                const isLast = authorization.length === index + 1;
                return html `
        ${content}
        ${!isLast ? html `<ui-divider></ui-divider>` : ''}
        `;
            }
            return html ``;
        });
    }
    renderEmptyAuthorization() {
        return html ``;
    }
    renderBasicAuthorization(auth) {
        return html `
    <basic-authorization
      .authorization="${auth}"
      ?readOnly="${this.readOnly}"
      class="auth-panel"
      canToggle
      canDelete
      @change="${this.handleAuthChange}"
      @delete="${this.handleAuthDelete}"
    ></basic-authorization>
    `;
    }
    renderBearerAuthorization(auth) {
        return html `
    <bearer-authorization
      .authorization="${auth}"
      ?readOnly="${this.readOnly}"
      class="auth-panel"
      canToggle
      canDelete
      @change="${this.handleAuthChange}"
      @delete="${this.handleAuthDelete}"
    ></bearer-authorization>
    `;
    }
    renderNtlmAuthorization(auth) {
        return html `
    <ntlm-authorization
      .authorization="${auth}"
      ?readOnly="${this.readOnly}"
      class="auth-panel"
      canToggle
      canDelete
      @change="${this.handleAuthChange}"
      @delete="${this.handleAuthDelete}"
    ></ntlm-authorization>
    `;
    }
    renderOauthAuthorization(auth) {
        return html `
    <oauth2-authorization
      .authorization="${auth}"
      ?readOnly="${this.readOnly}"
      class="auth-panel"
      canToggle
      canDelete
      @change="${this.handleAuthChange}"
      @delete="${this.handleAuthDelete}"
      .defaultRedirectUri="${this.oauth2RedirectUri}"
    ></oauth2-authorization>
    `;
    }
    renderOidcAuthorization(auth) {
        return html `
    <oidc-authorization
      .authorization="${auth}"
      ?readOnly="${this.readOnly}"
      class="auth-panel"
      canToggle
      canDelete
      @change="${this.handleAuthChange}"
      @delete="${this.handleAuthDelete}"
      .defaultRedirectUri="${this.oauth2RedirectUri}"
    ></oidc-authorization>
    `;
    }
    renderCCAuthorization(auth) {
        return html `
    <cc-authorization
      .authorization="${auth}"
      ?readOnly="${this.readOnly}"
      class="auth-panel"
      canToggle
      canDelete
      @change="${this.handleAuthChange}"
      @delete="${this.handleAuthDelete}"
    ></cc-authorization>
    `;
    }
    renderApiKeyAuthorization(auth) {
        return html `
    <apikey-authorization
      .authorization="${auth}"
      ?readOnly="${this.readOnly}"
      class="auth-panel"
      canToggle
      canDelete
      @change="${this.handleAuthChange}"
      @delete="${this.handleAuthDelete}"
    ></apikey-authorization>
    `;
    }
    renderHttpFlows(visible) {
        if (!visible) {
            return '';
        }
        const { flows = [] } = this;
        return html `
    <http-flows
      aria-label="HTTP fLows" 
      aria-labelledby="flows-tab" 
      id="flows" 
      role="tabpanel"
      .model="${flows}" 
      @change="${this.handleFlows}"
    ></http-flows>
    `;
    }
    renderAssertions(visible) {
        if (!visible) {
            return '';
        }
        const { assertions = [] } = this;
        return html `
    <http-assertions 
      aria-label="Assertions" 
      aria-labelledby="assertions-tab" 
      id="assertions" 
      role="tabpanel"
      .model="${assertions}" 
      @change="${this.handleAssertions}"
    ></http-assertions>
    `;
    }
    renderRequestConfig(visible) {
        if (!visible) {
            return nothing;
        }
        const { config } = this;
        return html `
    <http-request-config 
      aria-label="Request options" 
      aria-labelledby="config-tab" 
      id="config" 
      role="tabpanel"
      .config="${config}"
      @change="${this.handleConfig}"
    ></http-request-config>
    `;
    }
    /**
     * @param visible Whether the panel should be rendered
     * @returns The template for the Code snippets
     */
    renderSnippets(visible) {
        return html `
      <http-snippets 
        ?hidden="${!visible}"
        id="code-snippets"
        aria-describedby="code-snippets-tab"
        role="tabpanel"
        .request="${this.snippets}"
      ></http-snippets>`;
    }
    /**
     * @returns The template for the invalid content headers dialog
     */
    renderHeadersDialog() {
        const { contentHeadersDialogOpened } = this;
        return html `
    <ui-dialog .open="${contentHeadersDialogOpened}" @close="${this.handleContentWarningClose}">
      <ui-icon slot="icon" icon="warning"></ui-icon>
      <span slot="title">Headers are not valid</span>
      
      <div>
        <p>
          The <b>GET</b> request should not contain <b>content-*</b> headers. It may
          cause the server to behave unexpectedly.
        </p>
        <p><b>Do you want to continue?</b></p>
      </div>

      <ui-button type="text" value="dismiss" slot="button">Cancel request</ui-button>
      <ui-button type="text" value="confirm" slot="button">Continue</ui-button>
    </ui-dialog>`;
    }
}
__decorate([
    state()
], RequestEditor.prototype, "readingPayload", void 0);
__decorate([
    property({ type: Object })
], RequestEditor.prototype, "request", void 0);
__decorate([
    state()
], RequestEditor.prototype, "payload", void 0);
__decorate([
    state()
], RequestEditor.prototype, "contentType", void 0);
__decorate([
    property({ type: Array })
], RequestEditor.prototype, "authorization", void 0);
__decorate([
    property({ type: Array })
], RequestEditor.prototype, "assertions", void 0);
__decorate([
    property({ type: Array })
], RequestEditor.prototype, "flows", void 0);
__decorate([
    property({ type: String })
], RequestEditor.prototype, "oauth2RedirectUri", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], RequestEditor.prototype, "readOnly", void 0);
__decorate([
    property({ type: String, reflect: true })
], RequestEditor.prototype, "oauth2AuthorizationUri", void 0);
__decorate([
    property({ type: String, reflect: true })
], RequestEditor.prototype, "oauth2AccessTokenUri", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], RequestEditor.prototype, "ignoreContentOnGet", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], RequestEditor.prototype, "contentHeadersDialogOpened", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], RequestEditor.prototype, "loading", void 0);
__decorate([
    property({ type: Number, reflect: true })
], RequestEditor.prototype, "selectedTab", void 0);
__decorate([
    property({ type: Object })
], RequestEditor.prototype, "ui", void 0);
__decorate([
    property({ type: Object })
], RequestEditor.prototype, "config", void 0);
__decorate([
    state()
], RequestEditor.prototype, "snippets", void 0);
//# sourceMappingURL=RequestEditor.js.map