import * as i2 from '@rxap/open-api';
import { RxapOpenApiError, OpenApiConfigService, DEFAULT_OPEN_API_DATA_SOURCE_META_DATA, RXAP_OPEN_API_STRICT_VALIDATOR, DISABLE_SCHEMA_VALIDATION, DISABLE_VALIDATION, SchemaValidationMixin } from '@rxap/open-api';
import * as i0 from '@angular/core';
import { Injectable, Inject, Optional } from '@angular/core';
import * as i1 from '@angular/common/http';
import { HttpEventType, HttpClient } from '@angular/common/http';
import { __decorate, __metadata } from 'tslib';
import { deepMerge } from '@rxap/utilities';
import { BaseHttpDataSource } from '@rxap/data-source/http';
import { RxapDataSource, RXAP_DATA_SOURCE_REFRESH } from '@rxap/data-source';
import * as i3 from 'rxjs';
import { EMPTY, throwError } from 'rxjs';
import { tap, map, retry, catchError, filter, take, timeout } from 'rxjs/operators';
import { Mixin } from '@rxap/mixin';
import { isDefined } from '@rxap/rxjs';

class RxapOpenApiDataSourceError extends RxapOpenApiError {
    constructor(message, code, scope) {
        super(message, code, scope);
        this.addSubPackageName('data-source');
    }
}

var OpenApiDataSource_1;
function RxapOpenApiDataSource(operationIdOrMetadata, serverIndex = 0) {
    const metadata = typeof operationIdOrMetadata === 'string' ?
        {
            id: operationIdOrMetadata,
            serverIndex,
        } :
        operationIdOrMetadata;
    return function (target) {
        RxapDataSource(metadata)(target);
    };
}
let OpenApiDataSource = class OpenApiDataSource extends BaseHttpDataSource {
    static { OpenApiDataSource_1 = this; }
    constructor(http, openApiConfigService, metadata = null, refresh$ = null, strict = null, disableSchemaValidation = null, disableValidation = null) {
        super(http, metadata);
        this.openApiConfigService = openApiConfigService;
        this.strict = false;
        this.disableSchemaValidation = false;
        this.disableValidation = false;
        let operation;
        if (!this.metadata['operation']) {
            this.metadata['operation'] = operation = openApiConfigService.getOperation(this.metadata.id);
        }
        else {
            operation = this.metadata['operation'];
        }
        if (operation.method !== 'GET') {
            throw new Error('OpenApi DataSource only supports GET Operations!');
        }
        this.applyMetadata({
            id: operation.operationId,
            url: () => openApiConfigService.getBaseUrl(this.metadata['serverIndex']) + operation.path,
            method: 'GET',
        });
        this.strict = strict || this.metadata['strict'] || false;
        this.disableSchemaValidation = disableSchemaValidation || this.metadata['disableSchemaValidation'] || false;
        this.disableValidation = disableValidation || this.metadata['disableValidation'] || false;
    }
    get operation() {
        return this.metadata['operation'];
    }
    derive(id, metadata = this.metadata, isolated = false) {
        return new OpenApiDataSource_1(this.http, this.openApiConfigService, {
            ...deepMerge(this.metadata, metadata),
            id,
        }, isolated ? null : this.refresh$);
    }
    connect(viewer) {
        if (viewer.parameters) {
            if (!this.disableValidation) {
                this.validateParameters(this.operation, viewer.parameters, this.strict);
            }
        }
        else {
            if (viewer.viewChange === EMPTY || viewer.viewChange === undefined) {
                // set the viewer parameters to an empty parameter and test if that
                // is valid.
                viewer.parameters = {};
                if (!this.disableValidation) {
                    this.validateParameters(this.operation, viewer.parameters, this.strict);
                }
            }
        }
        return super.connect({
            ...viewer,
            ...this.buildHttpOptions(this.operation, viewer.parameters),
            // if the view change is an empty observable. Then dont apply the pipe logic
            // else the http request is never triggered
            viewChange: viewer.viewChange === EMPTY ? viewer.viewChange : viewer.viewChange?.pipe(tap(parameters => {
                if (!this.disableValidation) {
                    this.validateParameters(this.operation, parameters, this.strict);
                }
            }), map(parameters => this.buildHttpOptions(this.operation, parameters))),
        });
    }
    buildRequest(options) {
        return this.http.request(this.buildHttpRequest(options)).pipe(retry(this.metadata.retry ?? 0), catchError((response) => {
            this.interceptors?.forEach(interceptor => interceptor
                .next({
                response,
                options,
            }));
            return throwError(response);
        }), filter((event) => event.type === HttpEventType.Response), tap((response) => {
            if (!this.disableValidation) {
                this.validateResponse(this.operation, response, this.strict);
            }
        }), tap((response) => {
            this.interceptors?.forEach(interceptor => interceptor
                .next({
                response,
                options,
            }));
        }), map((event) => event.body), isDefined(), take(1), timeout(this.timeout));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiDataSource, deps: [{ token: HttpClient }, { token: OpenApiConfigService }, { token: DEFAULT_OPEN_API_DATA_SOURCE_META_DATA, optional: true }, { token: RXAP_DATA_SOURCE_REFRESH, optional: true }, { token: RXAP_OPEN_API_STRICT_VALIDATOR, optional: true }, { token: DISABLE_SCHEMA_VALIDATION, optional: true }, { token: DISABLE_VALIDATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiDataSource }); }
};
OpenApiDataSource = OpenApiDataSource_1 = __decorate([
    Mixin(SchemaValidationMixin),
    __metadata("design:paramtypes", [HttpClient,
        OpenApiConfigService, Object, Object, Object, Object, Object])
], OpenApiDataSource);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiDataSource, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.HttpClient, decorators: [{
                    type: Inject,
                    args: [HttpClient]
                }] }, { type: i2.OpenApiConfigService, decorators: [{
                    type: Inject,
                    args: [OpenApiConfigService]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [DEFAULT_OPEN_API_DATA_SOURCE_META_DATA]
                }] }, { type: i3.Subject, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_DATA_SOURCE_REFRESH]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_OPEN_API_STRICT_VALIDATOR]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [DISABLE_SCHEMA_VALIDATION]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [DISABLE_VALIDATION]
                }] }] });

class OpenApiDataSourceLoader {
    constructor(openApiConfig, http) {
        this.openApiConfig = openApiConfig;
        this.http = http;
    }
    load(definitionId) {
        const operation = this.openApiConfig.getOperation(definitionId);
        if (operation) {
            return new OpenApiDataSource(this.http, this.openApiConfig, {
                id: definitionId,
                operation,
            });
        }
        return null;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiDataSourceLoader, deps: [{ token: OpenApiConfigService }, { token: HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiDataSourceLoader, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiDataSourceLoader, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [{ type: i2.OpenApiConfigService, decorators: [{
                    type: Inject,
                    args: [OpenApiConfigService]
                }] }, { type: i1.HttpClient, decorators: [{
                    type: Inject,
                    args: [HttpClient]
                }] }] });

// region 
// endregion

/**
 * Generated bundle index. Do not edit.
 */

export { OpenApiDataSource, OpenApiDataSourceLoader, RxapOpenApiDataSource, RxapOpenApiDataSourceError };
//# sourceMappingURL=rxap-open-api-data-source.mjs.map
