import { __esDecorate, __runInitializers } from "tslib";
import { html, nothing } from 'lit';
import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { ApiSchemaValues } from '@api-client/core/amf/ApiSchemaValues.js';
import { AmfNamespace } from '@api-client/core/amf/definitions/Namespace.js';
import { ApiSchemaGenerator } from '@api-client/core/amf/ApiSchemaGenerator.js';
import { QueryParameterProcessor } from '../../amf/lib/QueryParameterProcessor.js';
import { ApiDocumentationBase } from './ApiDocumentationBase.js';
import { Events } from '../../events/amf/Events.js';
import { joinTraitNames } from '../../amf/lib/Utils.js';
import * as UrlLib from '../../amf/lib/UrlUtils.js';
import { tablePropertyTemplate } from './SchemaCommonTemplates.js';
import '../../define/amf/api-request-document.js';
import '../../define/amf/api-response-document.js';
import '../../define/amf/api-security-requirement-document.js';
import '../../md/icons/ui-icon.js';
import '../../md/button/ui-filled-button.js';
import '../../md/tabs/ui-tabs.js';
import '../../md/tabs/ui-tab.js';
import '../../md/divider/ui-divider.js';
import '../../define/http/http-snippets.js';
let ApiOperationDocument = (() => {
    let _classSuper = ApiDocumentationBase;
    let _instanceExtraInitializers = [];
    let _set_serverId_decorators;
    let _set_baseUri_decorators;
    let _securityId_decorators;
    let _securityId_initializers = [];
    let _securityId_extraInitializers = [];
    let _responsesOpened_decorators;
    let _responsesOpened_initializers = [];
    let _responsesOpened_extraInitializers = [];
    let _securityOpened_decorators;
    let _securityOpened_initializers = [];
    let _securityOpened_extraInitializers = [];
    let _snippetsOpened_decorators;
    let _snippetsOpened_initializers = [];
    let _snippetsOpened_extraInitializers = [];
    let _selectedStatus_decorators;
    let _selectedStatus_initializers = [];
    let _selectedStatus_extraInitializers = [];
    let _callbacksOpened_decorators;
    let _callbacksOpened_initializers = [];
    let _callbacksOpened_extraInitializers = [];
    let _tryItButton_decorators;
    let _tryItButton_initializers = [];
    let _tryItButton_extraInitializers = [];
    let _asyncApi_decorators;
    let _asyncApi_initializers = [];
    let _asyncApi_extraInitializers = [];
    let _renderCodeSnippets_decorators;
    let _renderCodeSnippets_initializers = [];
    let _renderCodeSnippets_extraInitializers = [];
    let _showSecurity_decorators;
    let _showSecurity_initializers = [];
    let _showSecurity_extraInitializers = [];
    let _requestMimeType_decorators;
    let _requestMimeType_initializers = [];
    let _requestMimeType_extraInitializers = [];
    let _endpointId_decorators;
    let _endpointId_initializers = [];
    let _endpointId_extraInitializers = [];
    return class ApiOperationDocument extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _set_serverId_decorators = [property({ type: String, reflect: true })];
            _set_baseUri_decorators = [property({ type: String })];
            _securityId_decorators = [property({ type: String, reflect: true })];
            _responsesOpened_decorators = [property({ type: Boolean, reflect: true })];
            _securityOpened_decorators = [property({ type: Boolean, reflect: true })];
            _snippetsOpened_decorators = [property({ type: Boolean, reflect: true })];
            _selectedStatus_decorators = [property({ type: String })];
            _callbacksOpened_decorators = [property({ type: Boolean, reflect: true })];
            _tryItButton_decorators = [property({ type: Boolean, reflect: true })];
            _asyncApi_decorators = [property({ type: Boolean, reflect: true })];
            _renderCodeSnippets_decorators = [property({ type: Boolean, reflect: true })];
            _showSecurity_decorators = [property({ type: Boolean, reflect: true })];
            _requestMimeType_decorators = [property({ type: String })];
            _endpointId_decorators = [property({ type: String })];
            __esDecorate(this, null, _set_serverId_decorators, { kind: "setter", name: "serverId", static: false, private: false, access: { has: obj => "serverId" in obj, set: (obj, value) => { obj.serverId = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _set_baseUri_decorators, { kind: "setter", name: "baseUri", static: false, private: false, access: { has: obj => "baseUri" in obj, set: (obj, value) => { obj.baseUri = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _securityId_decorators, { kind: "accessor", name: "securityId", static: false, private: false, access: { has: obj => "securityId" in obj, get: obj => obj.securityId, set: (obj, value) => { obj.securityId = value; } }, metadata: _metadata }, _securityId_initializers, _securityId_extraInitializers);
            __esDecorate(this, null, _responsesOpened_decorators, { kind: "accessor", name: "responsesOpened", static: false, private: false, access: { has: obj => "responsesOpened" in obj, get: obj => obj.responsesOpened, set: (obj, value) => { obj.responsesOpened = value; } }, metadata: _metadata }, _responsesOpened_initializers, _responsesOpened_extraInitializers);
            __esDecorate(this, null, _securityOpened_decorators, { kind: "accessor", name: "securityOpened", static: false, private: false, access: { has: obj => "securityOpened" in obj, get: obj => obj.securityOpened, set: (obj, value) => { obj.securityOpened = value; } }, metadata: _metadata }, _securityOpened_initializers, _securityOpened_extraInitializers);
            __esDecorate(this, null, _snippetsOpened_decorators, { kind: "accessor", name: "snippetsOpened", static: false, private: false, access: { has: obj => "snippetsOpened" in obj, get: obj => obj.snippetsOpened, set: (obj, value) => { obj.snippetsOpened = value; } }, metadata: _metadata }, _snippetsOpened_initializers, _snippetsOpened_extraInitializers);
            __esDecorate(this, null, _selectedStatus_decorators, { kind: "accessor", name: "selectedStatus", static: false, private: false, access: { has: obj => "selectedStatus" in obj, get: obj => obj.selectedStatus, set: (obj, value) => { obj.selectedStatus = value; } }, metadata: _metadata }, _selectedStatus_initializers, _selectedStatus_extraInitializers);
            __esDecorate(this, null, _callbacksOpened_decorators, { kind: "accessor", name: "callbacksOpened", static: false, private: false, access: { has: obj => "callbacksOpened" in obj, get: obj => obj.callbacksOpened, set: (obj, value) => { obj.callbacksOpened = value; } }, metadata: _metadata }, _callbacksOpened_initializers, _callbacksOpened_extraInitializers);
            __esDecorate(this, null, _tryItButton_decorators, { kind: "accessor", name: "tryItButton", static: false, private: false, access: { has: obj => "tryItButton" in obj, get: obj => obj.tryItButton, set: (obj, value) => { obj.tryItButton = value; } }, metadata: _metadata }, _tryItButton_initializers, _tryItButton_extraInitializers);
            __esDecorate(this, null, _asyncApi_decorators, { kind: "accessor", name: "asyncApi", static: false, private: false, access: { has: obj => "asyncApi" in obj, get: obj => obj.asyncApi, set: (obj, value) => { obj.asyncApi = value; } }, metadata: _metadata }, _asyncApi_initializers, _asyncApi_extraInitializers);
            __esDecorate(this, null, _renderCodeSnippets_decorators, { kind: "accessor", name: "renderCodeSnippets", static: false, private: false, access: { has: obj => "renderCodeSnippets" in obj, get: obj => obj.renderCodeSnippets, set: (obj, value) => { obj.renderCodeSnippets = value; } }, metadata: _metadata }, _renderCodeSnippets_initializers, _renderCodeSnippets_extraInitializers);
            __esDecorate(this, null, _showSecurity_decorators, { kind: "accessor", name: "showSecurity", static: false, private: false, access: { has: obj => "showSecurity" in obj, get: obj => obj.showSecurity, set: (obj, value) => { obj.showSecurity = value; } }, metadata: _metadata }, _showSecurity_initializers, _showSecurity_extraInitializers);
            __esDecorate(this, null, _requestMimeType_decorators, { kind: "accessor", name: "requestMimeType", static: false, private: false, access: { has: obj => "requestMimeType" in obj, get: obj => obj.requestMimeType, set: (obj, value) => { obj.requestMimeType = value; } }, metadata: _metadata }, _requestMimeType_initializers, _requestMimeType_extraInitializers);
            __esDecorate(this, null, _endpointId_decorators, { kind: "accessor", name: "endpointId", static: false, private: false, access: { has: obj => "endpointId" in obj, get: obj => obj.endpointId, set: (obj, value) => { obj.endpointId = value; } }, metadata: _metadata }, _endpointId_initializers, _endpointId_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        endpointValue = __runInitializers(this, _instanceExtraInitializers);
        operationValue;
        serversValue;
        responsesValue;
        serverIdValue;
        baseUriValue;
        urlValue;
        versionValue;
        protocolsValue;
        snippetsPayloadValue;
        snippetsHeadersValue;
        snippetsParametersValue;
        /**
         * The id of the currently selected server to use to construct the URL.
         * If not set a first server in the API servers array is used.
         * @attribute
         */
        get serverId() {
            return this.serverIdValue;
        }
        set serverId(value) {
            const old = this.serverIdValue;
            if (old === value) {
                return;
            }
            this.serverIdValue = value;
            this.computeUrlValue();
            this.computeParametersValue();
            this.requestUpdate();
        }
        /**
         * The computed list of servers.
         */
        get servers() {
            return this.serversValue;
        }
        /**
         * The current server in use.
         */
        get server() {
            const servers = this.serversValue;
            const serverId = this.serverIdValue;
            let server;
            if (Array.isArray(servers) && servers.length) {
                if (serverId) {
                    server = servers.find((item) => item.id === serverId);
                }
                else {
                    ;
                    [server] = servers;
                }
            }
            return server;
        }
        get operation() {
            return this.operationValue;
        }
        set operation(value) {
            const old = this.operationValue;
            if (old === value) {
                return;
            }
            this.operationValue = value;
            this.processGraph();
        }
        get endpoint() {
            return this.endpointValue;
        }
        set endpoint(value) {
            const old = this.endpointValue;
            if (old === value) {
                return;
            }
            this.endpointValue = value;
            this.computeUrlValue();
            this.computeParametersValue();
            this.requestUpdate();
        }
        /**
         * A property to set to override AMF's model base URI information.
         * When this property is set, the `endpointUri` property is recalculated.
         * @attribute
         */
        get baseUri() {
            return this.baseUriValue;
        }
        set baseUri(value) {
            const old = this.baseUriValue;
            if (old === value) {
                return;
            }
            this.baseUriValue = value;
            this.computeUrlValue();
            this.computeParametersValue();
            this.requestUpdate();
        }
        /**
         * The computed URI for the endpoint.
         */
        get endpointUri() {
            return this.urlValue;
        }
        get snippetsUri() {
            const base = this.urlValue || '';
            const query = this.snippetsParametersValue || '';
            return `${base}${query}`;
        }
        /**
         * The computed list of responses for this operation.
         */
        get responses() {
            return this.responsesValue;
        }
        /**
         * The API's protocols.
         */
        get protocols() {
            return this.protocolsValue;
        }
        get version() {
            return this.versionValue;
        }
        #securityId_accessor_storage = __runInitializers(this, _securityId_initializers, void 0);
        /**
         * The domain id of the currently selected security to render.
         * This is only used when a multiple security schemes are applied to the operation.
         * @attribute
         */
        get securityId() { return this.#securityId_accessor_storage; }
        set securityId(value) { this.#securityId_accessor_storage = value; }
        #responsesOpened_accessor_storage = (__runInitializers(this, _securityId_extraInitializers), __runInitializers(this, _responsesOpened_initializers, void 0));
        /**
         * When set it opens the response section
         * @attribute
         */
        get responsesOpened() { return this.#responsesOpened_accessor_storage; }
        set responsesOpened(value) { this.#responsesOpened_accessor_storage = value; }
        #securityOpened_accessor_storage = (__runInitializers(this, _responsesOpened_extraInitializers), __runInitializers(this, _securityOpened_initializers, void 0));
        /**
         * When set it opens the security section
         * @attribute
         */
        get securityOpened() { return this.#securityOpened_accessor_storage; }
        set securityOpened(value) { this.#securityOpened_accessor_storage = value; }
        #snippetsOpened_accessor_storage = (__runInitializers(this, _securityOpened_extraInitializers), __runInitializers(this, _snippetsOpened_initializers, void 0));
        /**
         * When set it opens the code snippets section
         * @attribute
         */
        get snippetsOpened() { return this.#snippetsOpened_accessor_storage; }
        set snippetsOpened(value) { this.#snippetsOpened_accessor_storage = value; }
        #selectedStatus_accessor_storage = (__runInitializers(this, _snippetsOpened_extraInitializers), __runInitializers(this, _selectedStatus_initializers, void 0));
        /**
         * The selected status code in the responses section.
         * @attribute
         */
        get selectedStatus() { return this.#selectedStatus_accessor_storage; }
        set selectedStatus(value) { this.#selectedStatus_accessor_storage = value; }
        #callbacksOpened_accessor_storage = (__runInitializers(this, _selectedStatus_extraInitializers), __runInitializers(this, _callbacksOpened_initializers, void 0));
        /**
         * Whether the callbacks section is opened.
         * @attribute
         */
        get callbacksOpened() { return this.#callbacksOpened_accessor_storage; }
        set callbacksOpened(value) { this.#callbacksOpened_accessor_storage = value; }
        #tryItButton_accessor_storage = (__runInitializers(this, _callbacksOpened_extraInitializers), __runInitializers(this, _tryItButton_initializers, void 0));
        /**
         * When set it renders the "try it" button that dispatches the `tryit` event.
         * @attribute
         */
        get tryItButton() { return this.#tryItButton_accessor_storage; }
        set tryItButton(value) { this.#tryItButton_accessor_storage = value; }
        #asyncApi_accessor_storage = (__runInitializers(this, _tryItButton_extraInitializers), __runInitializers(this, _asyncApi_initializers, void 0));
        /**
         * When set it renders the view optimised for asynchronous API operation.
         * @attribute
         */
        get asyncApi() { return this.#asyncApi_accessor_storage; }
        set asyncApi(value) { this.#asyncApi_accessor_storage = value; }
        #renderCodeSnippets_accessor_storage = (__runInitializers(this, _asyncApi_extraInitializers), __runInitializers(this, _renderCodeSnippets_initializers, void 0));
        /**
         * When set it renders code examples section is the documentation
         * @attribute
         */
        get renderCodeSnippets() { return this.#renderCodeSnippets_accessor_storage; }
        set renderCodeSnippets(value) { this.#renderCodeSnippets_accessor_storage = value; }
        #showSecurity_accessor_storage = (__runInitializers(this, _renderCodeSnippets_extraInitializers), __runInitializers(this, _showSecurity_initializers, void 0));
        /**
         * When set it renders security documentation when applicable
         * @attribute
         */
        get showSecurity() { return this.#showSecurity_accessor_storage; }
        set showSecurity(value) { this.#showSecurity_accessor_storage = value; }
        #requestMimeType_accessor_storage = (__runInitializers(this, _showSecurity_extraInitializers), __runInitializers(this, _requestMimeType_initializers, void 0));
        /**
         * The currently rendered request panel mime type.
         * @attribute
         */
        get requestMimeType() { return this.#requestMimeType_accessor_storage; }
        set requestMimeType(value) { this.#requestMimeType_accessor_storage = value; }
        #endpointId_accessor_storage = (__runInitializers(this, _requestMimeType_extraInitializers), __runInitializers(this, _endpointId_initializers, void 0));
        /**
         * Optional. The parent endpoint id. When set it uses this value to query for the endpoint
         * instead of querying for a parent through the operation id.
         * Also, when `endpoint` is set and the `endpointId` match then it ignores querying for
         * the endpoint.
         * @attribute
         */
        get endpointId() { return this.#endpointId_accessor_storage; }
        set endpointId(value) { this.#endpointId_accessor_storage = value; }
        async processGraph() {
            await this.queryEndpoint();
            await this.queryOperation();
            await this.queryServers();
            await this.queryProtocols();
            await this.queryResponses();
            this.preselectResponse();
            this.preselectSecurity();
            this.computeUrlValue();
            this.computeParametersValue();
            this.computeSnippetsPayload();
            this.computeSnippetsHeaders();
            this.requestUpdate();
            await this.updateComplete;
            this.dispatchEvent(new Event('graphload'));
        }
        /**
         * Queries the store for the operation data, when needed.
         */
        async queryOperation() {
            const { domainId } = this;
            if (!domainId) {
                // this.operationValue = undefined;
                return;
            }
            if (this.operationValue && this.operationValue.id === domainId) {
                // in case the operation model was provided via the property setter.
                return;
            }
            try {
                const endpointId = this.endpointValue && this.endpointValue.id;
                const info = await Events.Operation.get(this, domainId, endpointId);
                this.operationValue = info;
            }
            catch (e) {
                const ex = e;
                Events.Telemetry.exception(this, ex.message, false);
                Events.Reporting.error(this, ex, `Unable to query for API operation data: ${ex.message}`, this.localName);
            }
        }
        /**
         * Queries the store for the endpoint data.
         */
        async queryEndpoint() {
            const { domainId, endpointId } = this;
            if (!domainId) {
                // this.endpointValue = undefined;
                return;
            }
            if (this.endpointValue && this.endpointValue.id === endpointId) {
                // in case the endpoint model was provided via the property setter.
                return;
            }
            this.endpointValue = undefined;
            try {
                const info = await (endpointId
                    ? Events.Endpoint.get(this, endpointId)
                    : Events.Operation.getParent(this, domainId));
                this.endpointValue = info;
            }
            catch (e) {
                const ex = e;
                Events.Telemetry.exception(this, ex.message, false);
                Events.Reporting.error(this, ex, `Unable to query for API endpoint data: ${ex.message}`, this.localName);
            }
        }
        /**
         * Queries for the current servers value.
         */
        async queryServers() {
            const { domainId } = this;
            const endpointId = this.endpointValue && this.endpointValue.id;
            try {
                const info = await Events.Server.query(this, {
                    endpointId,
                    methodId: domainId,
                });
                this.serversValue = info;
            }
            catch (e) {
                const ex = e;
                this.serversValue = undefined;
                Events.Telemetry.exception(this, ex.message, false);
                Events.Reporting.error(this, ex, `Unable to query for API servers: ${ex.message}`, this.localName);
            }
        }
        /**
         * Queries the API store for the API protocols list.
         */
        async queryProtocols() {
            this.protocolsValue = undefined;
            try {
                const info = await Events.Api.protocols(this);
                this.protocolsValue = info;
            }
            catch (e) {
                const ex = e;
                Events.Telemetry.exception(this, ex.message, false);
                Events.Reporting.error(this, ex, `Unable to query for API protocols list: ${ex.message}`, this.localName);
            }
        }
        /**
         * Queries the API store for the API version value.
         */
        async queryVersion() {
            this.versionValue = undefined;
            try {
                const info = await Events.Api.version(this);
                this.versionValue = info;
            }
            catch (e) {
                const ex = e;
                Events.Telemetry.exception(this, ex.message, false);
                Events.Reporting.error(this, ex, `Unable to query for API version value: ${ex.message}`, this.localName);
            }
        }
        /**
         * Queries for the responses data of the current operation.
         */
        async queryResponses() {
            this.responsesValue = undefined;
            const { operation } = this;
            if (!operation) {
                return;
            }
            const { responses = [] } = operation;
            if (!responses.length) {
                return;
            }
            this.responsesValue = responses;
        }
        /**
         * Updates the `selectedStatus` if not selected or the current selection doesn't
         * exists in the current list of responses.
         */
        preselectResponse() {
            const responses = this.responsesValue;
            if (!Array.isArray(responses) || !responses.length) {
                return;
            }
            responses.sort((a, b) => {
                if (a.statusCode === b.statusCode) {
                    return 0;
                }
                return Number(a.statusCode) > Number(b.statusCode) ? 1 : -1;
            });
            const { selectedStatus } = this;
            if (!selectedStatus) {
                this.selectedStatus = responses[0].statusCode;
                return;
            }
            const selected = responses.find((item) => item.statusCode === selectedStatus);
            if (selected) {
                return;
            }
            this.selectedStatus = responses[0].statusCode;
        }
        /**
         * Updates the `securityId` if not selected or the current selection doesn't
         * exists in the current list of security.
         */
        preselectSecurity() {
            const { operation, showSecurity: renderSecurity, securityId } = this;
            if (!renderSecurity || !operation || !Array.isArray(operation.security) || !operation.security.length) {
                return;
            }
            if (!securityId) {
                this.securityId = operation.security[0].id;
                return;
            }
            const selected = operation.security.find((item) => item.id === securityId);
            if (selected) {
                return;
            }
            this.securityId = operation.security[0].id;
        }
        /**
         * Computes the URL value for the current serves, selected server, and endpoint's path.
         */
        computeUrlValue() {
            if (this.asyncApi) {
                return;
            }
            const { protocols, version, server, baseUri } = this;
            const endpoint = this.endpointValue;
            const url = UrlLib.computeEndpointUri({ baseUri, server, endpoint, protocols, version });
            this.urlValue = url;
        }
        /**
         * Computes query parameters for the code snippets.
         */
        computeParametersValue() {
            this.snippetsParametersValue = undefined;
            const { operation } = this;
            if (!operation) {
                return;
            }
            const { request } = operation;
            if (!request) {
                return;
            }
            const { queryParameters, queryString } = request;
            let params;
            if (Array.isArray(queryParameters) && queryParameters.length) {
                params = queryParameters;
            }
            else if (queryString) {
                const factory = new QueryParameterProcessor();
                const items = factory.collectOperationParameters(request.queryString, 'query');
                if (Array.isArray(items) && items.length) {
                    params = items.map((i) => i.parameter);
                }
            }
            if (!params || !params.length) {
                return;
            }
            const qp = {};
            params.forEach((param) => {
                const { required, schema, paramName, name } = param;
                if (!required) {
                    return;
                }
                const parameterName = paramName || name;
                if (!parameterName) {
                    return;
                }
                const anySchema = schema;
                const { defaultValueStr, examples = [] } = anySchema;
                if (defaultValueStr) {
                    qp[parameterName] = defaultValueStr;
                }
                else if (examples.length) {
                    const exp = examples.find((e) => e.value);
                    if (exp && exp.value) {
                        qp[parameterName] = exp.value;
                    }
                }
                else {
                    const value = ApiSchemaValues.generateDefaultValue(schema);
                    if (value || value === false || value === 0 || value === null) {
                        qp[parameterName] = value;
                    }
                    // if (typeof value === 'undefined') {
                    //   qp[parameterName] = '';
                    // } else {
                    //   qp[parameterName] = value;
                    // }
                }
            });
            const value = UrlLib.applyUrlParameters('', qp, true);
            this.snippetsParametersValue = value;
        }
        /**
         * Computes payload value for the code snippets.
         */
        computeSnippetsPayload() {
            this.snippetsPayloadValue = undefined;
            if (this.asyncApi) {
                return;
            }
            const { operation, requestMimeType } = this;
            if (!operation || !requestMimeType) {
                return;
            }
            const { request } = operation;
            if (!request) {
                return;
            }
            const { payloads = [] } = request;
            if (!payloads.length) {
                return;
            }
            const payload = payloads.find((p) => p.mediaType === requestMimeType);
            if (!payload) {
                return;
            }
            const { examples = [], schema } = payload;
            let examplesCopy = [...examples];
            const anySchema = schema;
            if (Array.isArray(anySchema.examples) && anySchema.examples.length) {
                examplesCopy = examplesCopy.concat(anySchema.examples);
            }
            examplesCopy = examplesCopy.filter((i) => !!i.value || !!i.structuredValue);
            let payloadValue;
            if (examplesCopy.length) {
                const example = examplesCopy.find((e) => !!e.value);
                if (example) {
                    payloadValue = this.evaluateExample(example, requestMimeType);
                }
            }
            if (!payloadValue) {
                payloadValue = ApiSchemaGenerator.asExample(schema, requestMimeType, {
                    renderExamples: true,
                    renderOptional: true,
                });
            }
            if (payloadValue && payloadValue.renderValue) {
                this.snippetsPayloadValue = payloadValue.renderValue;
            }
        }
        /**
         * Computes headers value for the code snippets.
         */
        computeSnippetsHeaders() {
            this.snippetsHeadersValue = undefined;
            if (this.asyncApi) {
                return;
            }
            const { operation, requestMimeType } = this;
            if (!operation) {
                return;
            }
            const { request, method } = operation;
            if (!request) {
                return;
            }
            const { headers = [] } = request;
            const parts = [];
            let hasMime = false;
            headers.forEach((param) => {
                const { paramName, name, schema } = param;
                if (!schema || !schema.types.includes(AmfNamespace.aml.vocabularies.shapes.ScalarShape)) {
                    return;
                }
                const typedScalar = schema;
                let value = ApiSchemaValues.readInputValue(param, typedScalar, { fromExamples: true });
                if (Array.isArray(value)) {
                    value = value.join(',');
                }
                if (typeof value !== 'undefined') {
                    const headerName = paramName || name || '';
                    if (headerName.toLowerCase() === 'content-type') {
                        hasMime = true;
                    }
                    const header = `${paramName || name}: ${value}`;
                    parts.push(header);
                }
            });
            if (!hasMime && requestMimeType && method !== 'get') {
                parts.push(`content-type: ${requestMimeType}`);
            }
            this.snippetsHeadersValue = parts.join('\n');
        }
        /**
         * A handler for the status code tab selection.
         */
        handleStatusCode(e) {
            const { item } = e.detail;
            const { status } = item.dataset;
            if (!status) {
                return;
            }
            this.selectedStatus = status;
        }
        /**
         * A handler for the status code tab selection.
         */
        handleSecuritySelection(e) {
            const { item } = e.detail;
            const { id } = item.dataset;
            if (!id) {
                return;
            }
            this.securityId = id;
        }
        /**
         * A handler for the try it button click.
         * It dispatches the `tryit` custom event.
         */
        handleTryIt() {
            const { operation, asyncApi } = this;
            if (!operation || asyncApi) {
                return;
            }
            const { id } = operation;
            const detail = { id };
            const config = {
                bubbles: true,
                composed: true,
                detail,
            };
            this.dispatchEvent(new CustomEvent('tryit', config));
        }
        /**
         * A handler for the request panel mime type change.
         */
        handleRequestMimeChange(e) {
            const panel = e.target;
            this.requestMimeType = panel.mimeType;
            this.computeSnippetsPayload();
            this.computeSnippetsHeaders();
            this.requestUpdate();
        }
        render() {
            const op = this.operationValue;
            if (!op) {
                return html ``;
            }
            return html `
      ${this.renderTitle(op)} ${this.renderSummary(op)} ${this.renderUrl(op)} ${this.renderTraits(op)}
      ${this.renderDeprecated(op)} ${this.descriptionTemplate(op.description)} ${this.renderMetaData(op)}
      ${this.customDomainPropertiesTemplate(op.customDomainProperties)} ${this.renderRequestTemplate()}
      ${this.renderCallbacks(op)} ${this.renderSnippets(op)} ${this.renderResponse()} ${this.renderSecuritySection(op)}
    `;
        }
        /**
         * @returns The template for the Operation title.
         */
        renderTitle(operation) {
            const { name, method, deprecated } = operation;
            const label = name || method;
            const labelClasses = {
                'label': true,
                'text-selectable': true,
                deprecated,
            };
            const subTitle = this.asyncApi ? 'Async operation' : 'API operation';
            return html `
      <div class="operation-header">
        <div class="operation-title">
          <span class="${classMap(labelClasses)}">${label}</span>
          ${this.renderTryIt()}
        </div>
        <p class="sub-header">${subTitle}</p>
      </div>
    `;
        }
        /**
         * @returns The template for the Operation traits.
         */
        renderTraits(operation) {
            const { extends: traits } = operation;
            if (!traits || !traits.length) {
                return '';
            }
            const value = joinTraitNames(traits);
            return html ` <section class="extensions">
      <p>Mixes in <span class="trait-name text-selectable">${value}</span>.</p>
    </section>`;
        }
        /**
         * @returns The template for the operation summary filed.
         */
        renderSummary(operation) {
            const { summary } = operation;
            if (!summary) {
                return '';
            }
            return html ` <p class="summary text-selectable">${summary}</p> `;
        }
        /**
         * @returns The template for the Operation meta information.
         */
        renderMetaData(operation) {
            const { operationId } = operation;
            const result = [];
            if (operationId) {
                result.push(tablePropertyTemplate('Operation ID', operationId, 'operation-id'));
            }
            if (result.length) {
                return result;
            }
            return '';
        }
        /**
         * @returns The template for the deprecated message.
         */
        renderDeprecated(operation) {
            const { deprecated } = operation;
            if (!deprecated) {
                return '';
            }
            return html `
      <div class="deprecated-message">
        <ui-icon icon="warning"></ui-icon>
        <span class="message text-selectable"> This operation is marked as deprecated. </span>
      </div>
    `;
        }
        /**
         * @returns The template for the operation's URL.
         */
        renderUrl(operation) {
            if (this.asyncApi) {
                return '';
            }
            const url = this.urlValue;
            const { method } = operation;
            return html `
      <div class="endpoint-url">
        <div class="http-label" data-method="${method}">${method}</div>
        <div class="url-value text-selectable">${url}</div>
      </div>
    `;
        }
        /**
         * @returns The template for the operation's request documentation element.
         */
        renderRequestTemplate() {
            const { operation } = this;
            if (!operation) {
                return '';
            }
            const { server, endpoint } = this;
            return html `
      <api-request-document
        .domainId="${operation.request && operation.request.id}"
        .request="${operation.request}"
        .server=${server}
        .endpoint=${endpoint}
        @mimechange="${this.handleRequestMimeChange}"
      ></api-request-document>
    `;
        }
        renderCallbacks(operation) {
            const { callbacks } = operation;
            if (!Array.isArray(callbacks) || !callbacks.length) {
                return '';
            }
            const content = callbacks.map((callback) => this.renderCallback(callback));
            return this.paramsSectionTemplate('Callbacks', 'callbacksOpened', content);
        }
        /**
         * @returns The template for the operation's request documentation element.
         */
        renderCallback(callback) {
            const { name, endpoint } = callback;
            if (!endpoint) {
                return html ``;
            }
            const { operations = [] } = endpoint;
            const [operation] = operations;
            if (!operation) {
                return html ``;
            }
            return html `
      <div class="callback-section">
        <div class="heading4 table-title">${name}</div>
        <api-operation-document
          .domainId="${operation.id}"
          .operation="${operation}"
          .serverId="${this.serverId}"
          .endpoint="${endpoint}"
          data-domain-id="${operation.id}"
          class="operation"
        ></api-operation-document>
      </div>
    `;
        }
        renderResponse() {
            const responses = this.responsesValue;
            if (!Array.isArray(responses) || !responses.length) {
                return '';
            }
            const content = html ` ${this.renderResponseTabs(responses)} ${this.renderResponseContent(responses)} `;
            return this.paramsSectionTemplate('Responses', 'responsesOpened', content);
        }
        /**
         * @param responses The responses to render.
         * @returns The template for the responses selector.
         */
        renderResponseTabs(responses) {
            const { selectedStatus } = this;
            const filtered = responses.filter((item) => !!item.statusCode);
            if (!filtered.length) {
                return '';
            }
            return html `
      <div class="status-codes-selector">
        <ui-tabs .selected="${selectedStatus}" @select="${this.handleStatusCode}" priority="secondary" scrollable>
          ${filtered.map((item) => html `<ui-tab aria-controls="status${item.statusCode || 0}" data-status="${item.statusCode || 0}"
                >${item.statusCode}</ui-tab
              >`)}
        </ui-tabs>
      </div>
    `;
        }
        /**
         * @param responses The responses to render.
         * @returns The template for the currently selected response.
         */
        renderResponseContent(responses) {
            const { selectedStatus } = this;
            const response = responses.find((item) => item.statusCode === selectedStatus);
            if (!response) {
                return html `<div class="empty-info" id="status${selectedStatus}">
        Select a response to render the documentation.
      </div>`;
            }
            return html `
      <api-response-document
        id="status${selectedStatus}"
        .domainId="${response.id}"
        .response="${response}"
        class="method-response"
      ></api-response-document>
    `;
        }
        /**
         * @returns The template for the security list section.
         */
        renderSecuritySection(operation) {
            const { showSecurity: renderSecurity, securityId } = this;
            if (!renderSecurity || !operation || !Array.isArray(operation.security) || !operation.security.length) {
                return '';
            }
            const { security } = operation;
            const content = [];
            if (security.length === 1) {
                content.push(this.renderSecurity(security[0]));
            }
            else if (securityId) {
                content.push(this.renderSecuritySelector(operation));
                const item = security.find((i) => i.id === securityId);
                if (item) {
                    content.push(this.renderSecurity(item));
                }
            }
            return this.paramsSectionTemplate('Security', 'securityOpened', content);
        }
        renderSecurity(security) {
            return html `<api-security-requirement-document
      .domainId="${security.id}"
      .securityRequirement="${security}"
      id="security${security.id}"
    ></api-security-requirement-document>`;
        }
        renderSecuritySelector(operation) {
            const { securityId } = this;
            const { security } = operation;
            return html `
      <div class="security-selector">
        <ui-tabs
          .selected="${securityId}"
          @select="${this.handleSecuritySelection}"
          scrollable
          selectedAttribute="data-id"
        >
          ${security.map((item) => this.renderSecurityTab(item))}
        </ui-tabs>
      </div>
    `;
        }
        renderSecurityTab(security) {
            const { name, schemes = [], id } = security;
            let label = 'unknown';
            if (name) {
                label = name;
            }
            else if (schemes.length) {
                const parts = schemes.map((i) => i.name).filter((i) => !!i);
                if (parts.length) {
                    label = parts.join('/');
                }
            }
            return html `<ui-tab data-id="${id}" aria-controls="security${id}">${label}</ui-tab>`;
        }
        /**
         * @returns The template for the "try it" button.
         */
        renderTryIt() {
            if (!this.tryItButton) {
                return nothing;
            }
            return html ` <ui-filled-button class="action-button" @click="${this.handleTryIt}">Try it</ui-filled-button> `;
        }
        /**
         * @returns The template for the code snippets.
         */
        renderSnippets(operation) {
            if (!this.renderCodeSnippets || this.asyncApi) {
                return '';
            }
            const request = {
                url: this.snippetsUri || '',
                headers: this.snippetsHeadersValue,
                method: (operation.method || '').toUpperCase(),
                payload: this.snippetsPayloadValue,
            };
            const content = html `<http-snippets .request="${request}"></http-snippets>`;
            return this.paramsSectionTemplate('Code snippets', 'snippetsOpened', content);
        }
        constructor() {
            super(...arguments);
            __runInitializers(this, _endpointId_extraInitializers);
        }
    };
})();
/**
 * A web component that renders the documentation page for an API operation built from
 * the AMF graph model.
 *
 * @fires tryit
 */
export default ApiOperationDocument;
//# sourceMappingURL=ApiOperationDocument.element.js.map