import { __esDecorate, __runInitializers } from "tslib";
import { html } from 'lit';
import { property } from 'lit/decorators.js';
import { ApiDocumentationBase } from './ApiDocumentationBase.js';
import { QueryParameterProcessor } from '../../amf/lib/QueryParameterProcessor.js';
import { Events } from '../../events/amf/Events.js';
import '../../define/amf/api-payload-document.js';
import '../../define/amf/api-parameter-document.js';
import '../../md/radio/ui-radio.js';
import '../../md/divider/ui-divider.js';
let ApiRequestDocument = (() => {
    let _classSuper = ApiDocumentationBase;
    let _parametersOpened_decorators;
    let _parametersOpened_initializers = [];
    let _parametersOpened_extraInitializers = [];
    let _headersOpened_decorators;
    let _headersOpened_initializers = [];
    let _headersOpened_extraInitializers = [];
    let _cookiesOpened_decorators;
    let _cookiesOpened_initializers = [];
    let _cookiesOpened_extraInitializers = [];
    let _payloadOpened_decorators;
    let _payloadOpened_initializers = [];
    let _payloadOpened_extraInitializers = [];
    let _mimeType_decorators;
    let _mimeType_initializers = [];
    let _mimeType_extraInitializers = [];
    let _server_decorators;
    let _server_initializers = [];
    let _server_extraInitializers = [];
    let _endpoint_decorators;
    let _endpoint_initializers = [];
    let _endpoint_extraInitializers = [];
    return class ApiRequestDocument extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _parametersOpened_decorators = [property({ type: Boolean, reflect: true })];
            _headersOpened_decorators = [property({ type: Boolean, reflect: true })];
            _cookiesOpened_decorators = [property({ type: Boolean, reflect: true })];
            _payloadOpened_decorators = [property({ type: Boolean, reflect: true })];
            _mimeType_decorators = [property({ type: String, reflect: true })];
            _server_decorators = [property({ type: Object })];
            _endpoint_decorators = [property({ type: Object })];
            __esDecorate(this, null, _parametersOpened_decorators, { kind: "accessor", name: "parametersOpened", static: false, private: false, access: { has: obj => "parametersOpened" in obj, get: obj => obj.parametersOpened, set: (obj, value) => { obj.parametersOpened = value; } }, metadata: _metadata }, _parametersOpened_initializers, _parametersOpened_extraInitializers);
            __esDecorate(this, null, _headersOpened_decorators, { kind: "accessor", name: "headersOpened", static: false, private: false, access: { has: obj => "headersOpened" in obj, get: obj => obj.headersOpened, set: (obj, value) => { obj.headersOpened = value; } }, metadata: _metadata }, _headersOpened_initializers, _headersOpened_extraInitializers);
            __esDecorate(this, null, _cookiesOpened_decorators, { kind: "accessor", name: "cookiesOpened", static: false, private: false, access: { has: obj => "cookiesOpened" in obj, get: obj => obj.cookiesOpened, set: (obj, value) => { obj.cookiesOpened = value; } }, metadata: _metadata }, _cookiesOpened_initializers, _cookiesOpened_extraInitializers);
            __esDecorate(this, null, _payloadOpened_decorators, { kind: "accessor", name: "payloadOpened", static: false, private: false, access: { has: obj => "payloadOpened" in obj, get: obj => obj.payloadOpened, set: (obj, value) => { obj.payloadOpened = value; } }, metadata: _metadata }, _payloadOpened_initializers, _payloadOpened_extraInitializers);
            __esDecorate(this, null, _mimeType_decorators, { kind: "accessor", name: "mimeType", static: false, private: false, access: { has: obj => "mimeType" in obj, get: obj => obj.mimeType, set: (obj, value) => { obj.mimeType = value; } }, metadata: _metadata }, _mimeType_initializers, _mimeType_extraInitializers);
            __esDecorate(this, null, _server_decorators, { kind: "accessor", name: "server", static: false, private: false, access: { has: obj => "server" in obj, get: obj => obj.server, set: (obj, value) => { obj.server = value; } }, metadata: _metadata }, _server_initializers, _server_extraInitializers);
            __esDecorate(this, null, _endpoint_decorators, { kind: "accessor", name: "endpoint", static: false, private: false, access: { has: obj => "endpoint" in obj, get: obj => obj.endpoint, set: (obj, value) => { obj.endpoint = value; } }, metadata: _metadata }, _endpoint_initializers, _endpoint_extraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        requestValue;
        payloadsValue;
        /**
         * @returns true when has cookie parameters definition
         */
        get hasCookieParameters() {
            const request = this.requestValue;
            if (!request) {
                return false;
            }
            return Array.isArray(request.cookieParameters) && !!request.cookieParameters.length;
        }
        /**
         * @returns true when has headers parameters definition
         */
        get hasHeaders() {
            const request = this.requestValue;
            if (!request) {
                return false;
            }
            return Array.isArray(request.headers) && !!request.headers.length;
        }
        /**
         * @returns true when has query parameters definition
         */
        get hasQueryParameters() {
            const request = this.requestValue;
            if (!request) {
                return false;
            }
            return Array.isArray(request.queryParameters) && !!request.queryParameters.length;
        }
        /**
         * @returns The combined list of path parameters in the server, endpoint, and the request.
         */
        get uriParameters() {
            const request = this.requestValue;
            const { server, endpoint } = this;
            let result = [];
            if (server && Array.isArray(server.variables) && server.variables.length) {
                result = result.concat(server.variables);
            }
            if (endpoint && Array.isArray(endpoint.parameters) && endpoint.parameters.length) {
                result = result.concat(endpoint.parameters);
            }
            if (request && Array.isArray(request.uriParameters) && request.uriParameters.length) {
                result = result.concat(request.uriParameters);
            }
            return result;
        }
        /**
         * @returns true when has query string definition
         */
        get hasQueryString() {
            const request = this.requestValue;
            if (!request) {
                return false;
            }
            return !!request.queryString;
        }
        get payloadValue() {
            const { mimeType } = this;
            const payloads = this.payloadsValue;
            if (!Array.isArray(payloads) || !payloads.length) {
                return undefined;
            }
            if (!mimeType) {
                return payloads[0];
            }
            return payloads.find((item) => item.mediaType === mimeType);
        }
        get request() {
            return this.requestValue;
        }
        set request(value) {
            const old = this.requestValue;
            if (old === value) {
                return;
            }
            this.requestValue = value;
            this.processGraph();
        }
        #parametersOpened_accessor_storage = __runInitializers(this, _parametersOpened_initializers, void 0);
        /**
         * When set it opens the parameters section
         * @attribute
         */
        get parametersOpened() { return this.#parametersOpened_accessor_storage; }
        set parametersOpened(value) { this.#parametersOpened_accessor_storage = value; }
        #headersOpened_accessor_storage = (__runInitializers(this, _parametersOpened_extraInitializers), __runInitializers(this, _headersOpened_initializers, void 0));
        /**
         * When set it opens the headers section
         * @attribute
         */
        get headersOpened() { return this.#headersOpened_accessor_storage; }
        set headersOpened(value) { this.#headersOpened_accessor_storage = value; }
        #cookiesOpened_accessor_storage = (__runInitializers(this, _headersOpened_extraInitializers), __runInitializers(this, _cookiesOpened_initializers, void 0));
        /**
         * When set it opens the cookies section
         * @attribute
         */
        get cookiesOpened() { return this.#cookiesOpened_accessor_storage; }
        set cookiesOpened(value) { this.#cookiesOpened_accessor_storage = value; }
        #payloadOpened_accessor_storage = (__runInitializers(this, _cookiesOpened_extraInitializers), __runInitializers(this, _payloadOpened_initializers, void 0));
        /**
         * When set it opens the payload section
         * @attribute
         */
        get payloadOpened() { return this.#payloadOpened_accessor_storage; }
        set payloadOpened(value) { this.#payloadOpened_accessor_storage = value; }
        #mimeType_accessor_storage = (__runInitializers(this, _payloadOpened_extraInitializers), __runInitializers(this, _mimeType_initializers, void 0));
        /**
         * The currently selected media type for the payloads.
         * @attribute
         */
        get mimeType() { return this.#mimeType_accessor_storage; }
        set mimeType(value) { this.#mimeType_accessor_storage = value; }
        #server_accessor_storage = (__runInitializers(this, _mimeType_extraInitializers), __runInitializers(this, _server_initializers, void 0));
        /**
         * The current server in use.
         * It adds path parameters defined for the server.
         */
        get server() { return this.#server_accessor_storage; }
        set server(value) { this.#server_accessor_storage = value; }
        #endpoint_accessor_storage = (__runInitializers(this, _server_extraInitializers), __runInitializers(this, _endpoint_initializers, void 0));
        /**
         * The parent endpoint of this request.
         * It adds path parameters defined for the endpoint.
         */
        get endpoint() { return this.#endpoint_accessor_storage; }
        set endpoint(value) { this.#endpoint_accessor_storage = value; }
        queryParametersValue = __runInitializers(this, _endpoint_extraInitializers);
        async processGraph() {
            this.mimeType = undefined;
            await this.queryRequest();
            await this.queryPayloads();
            await this.processQueryParameters();
            this.preselectMime();
            this.requestUpdate();
            await this.updateComplete;
        }
        /**
         * Queries the store for the request data, when needed.
         */
        async queryRequest() {
            const { domainId } = this;
            if (!domainId) {
                // this.requestValue = undefined;
                return;
            }
            if (this.requestValue && this.requestValue.id === domainId) {
                // in case the request model was provided via the property setter.
                return;
            }
            try {
                const info = await Events.Request.get(this, domainId);
                this.requestValue = info;
            }
            catch (e) {
                this.requestValue = undefined;
                const ex = e;
                Events.Telemetry.exception(this, ex.message, false);
                Events.Reporting.error(this, ex, `Unable to query for API request data: ${ex.message}`, this.localName);
            }
        }
        async queryPayloads() {
            const { request } = this;
            if (!request || !request.payloads.length) {
                this.payloadsValue = undefined;
                return;
            }
            this.payloadsValue = request.payloads;
        }
        /**
         * Creates a parameter
         */
        async processQueryParameters() {
            this.queryParametersValue = undefined;
            const { request } = this;
            if (!request) {
                return;
            }
            const nodeShape = request.queryString;
            if (!nodeShape) {
                return;
            }
            const factory = new QueryParameterProcessor();
            const params = factory.collectOperationParameters(request.queryString, 'query');
            this.queryParametersValue = params;
        }
        /**
         * Pre-selects when needed the mime type for the current payload.
         */
        preselectMime() {
            const { mimeType } = this;
            const payloads = this.payloadsValue;
            if (!Array.isArray(payloads) || !payloads.length) {
                return;
            }
            const mime = [];
            let hasCurrent = false;
            payloads.forEach((item) => {
                if (item.mediaType) {
                    mime.push(item.mediaType);
                    if (!hasCurrent && item.mediaType === mimeType) {
                        hasCurrent = true;
                    }
                }
            });
            // do not change the selection when already exist.
            if (hasCurrent) {
                return;
            }
            if (!mime.length) {
                return;
            }
            const [first] = mime;
            this.mimeType = first;
            this.notifyMime();
        }
        mediaTypeSelectHandler(e) {
            const node = e.target;
            const { value } = node;
            this.mimeType = value;
            this.notifyMime();
        }
        /**
         * Dispatches the `mimechange` event.
         */
        notifyMime() {
            this.dispatchEvent(new Event('mimechange'));
        }
        render() {
            const { request, server, endpoint } = this;
            if (!request && !server && !endpoint) {
                return html ``;
            }
            return html `
      ${this.queryParamsTemplate()} ${this.headersTemplate()} ${this.cookiesTemplate()} ${this.payloadTemplate()}
    `;
        }
        /**
         * @return The template for the query parameters
         */
        queryParamsTemplate() {
            const { uriParameters, hasQueryParameters } = this;
            if (!hasQueryParameters && !uriParameters.length) {
                return '';
            }
            const { request } = this;
            let queryParameters = [];
            if (request && Array.isArray(request.queryParameters)) {
                queryParameters = request.queryParameters;
            }
            if (!queryParameters.length && this.queryParametersValue && this.queryParametersValue.length) {
                queryParameters = this.queryParametersValue.map((i) => i.parameter);
            }
            const content = [];
            uriParameters.forEach((param) => content.push(this.schemaItemTemplate(param, 'uri')));
            queryParameters.forEach((param) => content.push(this.schemaItemTemplate(param, 'query')));
            return this.paramsSectionTemplate('Parameters', 'parametersOpened', content.map((item, index) => {
                if (index === content.length - 1) {
                    return item;
                }
                return html `
          ${item}
          <ui-divider></ui-divider>
        `;
            }));
        }
        /**
         * @return The template for the headers
         */
        headersTemplate() {
            if (!this.hasHeaders) {
                return '';
            }
            const { request } = this;
            const content = request.headers.map((param) => this.schemaItemTemplate(param, 'header'));
            return this.paramsSectionTemplate('Headers', 'headersOpened', content);
        }
        /**
         * @return The template for the cookies list section
         */
        cookiesTemplate() {
            if (!this.hasCookieParameters) {
                return '';
            }
            const { request } = this;
            const content = request.cookieParameters.map((param) => this.schemaItemTemplate(param, 'cookie'));
            return this.paramsSectionTemplate('Cookies', 'cookiesOpened', content);
        }
        /**
         * @return The template for the payload section
         */
        payloadTemplate() {
            const payload = this.payloadValue;
            if (!payload) {
                return '';
            }
            const content = html `
      ${this.payloadSelectorTemplate()}
      <api-payload-document .domainId="${payload.id}" .payload="${payload}"></api-payload-document>
    `;
            return this.paramsSectionTemplate('Request body', 'payloadOpened', content);
        }
        /**
         * @return The template for the payload media type selector.
         */
        payloadSelectorTemplate() {
            const payloads = this.payloadsValue;
            if (!Array.isArray(payloads) || payloads.length < 2) {
                return '';
            }
            const mime = [];
            payloads.forEach((item) => {
                if (item.mediaType) {
                    mime.push(item.mediaType);
                }
            });
            if (!mime.length) {
                return '';
            }
            const mimeType = this.mimeType || mime[0];
            return html `
      <div class="media-type-selector">
        <span id="body-mime">Body content type</span>
        ${mime.map((item) => html `
            <label class="label-large">
              <ui-radio
                class="response-toggle"
                name="responseMime"
                value="${item}"
                .checked="${item === mimeType}"
                @change="${this.mediaTypeSelectHandler}"
              ></ui-radio>
              ${item}
            </label>
          `)}
      </div>
    `;
        }
    };
})();
/**
 * A web component that renders the documentation page for an API request object.
 */
export default ApiRequestDocument;
//# sourceMappingURL=ApiRequestDocument.element.js.map