import { __assign, __awaiter, __generator } from 'tslib';
import { BehaviorSubject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { Injectable, Optional, NgModule, SkipSelf } from '@angular/core';

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/config.interface.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var ApiConfig = /** @class */ (function () {
    function ApiConfig() {
    }
    return ApiConfig;
}());
if (false) {
    /** @type {?} */
    ApiConfig.prototype.baseUrl;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/mapper.interface.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @record
 */
function ApiMapperProtocol() { }
if (false) {
    /**
     * @template T
     * @param {?} data
     * @return {?}
     */
    ApiMapperProtocol.prototype.toPageResponse = function (data) { };
    /**
     * @param {?} data
     * @return {?}
     */
    ApiMapperProtocol.prototype.toPageRequest = function (data) { };
}
/**
 * @record
 */
function ApiParams() { }

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/pages.interface.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @record
 * @template T
 */
function ApiPageResponse() { }
if (false) {
    /** @type {?} */
    ApiPageResponse.prototype.totalPages;
    /** @type {?} */
    ApiPageResponse.prototype.totalEntries;
    /** @type {?} */
    ApiPageResponse.prototype.pageSize;
    /** @type {?} */
    ApiPageResponse.prototype.pageNumber;
    /** @type {?} */
    ApiPageResponse.prototype.data;
}
/**
 * @record
 */
function ApiPageRequest() { }
if (false) {
    /** @type {?} */
    ApiPageRequest.prototype.pageNumber;
    /** @type {?} */
    ApiPageRequest.prototype.pageSize;
    /** @type {?} */
    ApiPageRequest.prototype.query;
    /** @type {?} */
    ApiPageRequest.prototype.queryFields;
    /** @type {?} */
    ApiPageRequest.prototype.sort;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/datasource.interface.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var DataSourceRequest = /** @class */ (function () {
    function DataSourceRequest() {
        // Data.
        this._request$ = new BehaviorSubject(null);
        this._loading$ = new BehaviorSubject(true);
    }
    Object.defineProperty(DataSourceRequest.prototype, "loading", {
        get: /**
         * @return {?}
         */
        function () {
            return this._loading$.asObservable();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DataSourceRequest.prototype, "when", {
        get: /**
         * @return {?}
         */
        function () {
            return this._request$.pipe(filter((/**
             * @param {?} data
             * @return {?}
             */
            function (data) { return !!data; })));
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @return {?}
     */
    DataSourceRequest.prototype.startLoading = /**
     * @return {?}
     */
    function () {
        this._loading$.next(true);
    };
    /**
     * @return {?}
     */
    DataSourceRequest.prototype.stopLoading = /**
     * @return {?}
     */
    function () {
        this._loading$.next(false);
    };
    /**
     * @param {?=} params
     * @return {?}
     */
    DataSourceRequest.prototype.update = /**
     * @param {?=} params
     * @return {?}
     */
    function (params) {
        if (params === void 0) { params = {}; }
        /** @type {?} */
        var currentValue = this._request$.getValue();
        // Set the page number to 1 if the query or page size was changed.
        if (currentValue && params && (currentValue.query !== params.query || currentValue.pageSize !== params.pageSize)) {
            params.pageNumber = 1;
        }
        this._request$.next(__assign({}, currentValue, params));
    };
    return DataSourceRequest;
}());
if (false) {
    /**
     * @type {?}
     * @private
     */
    DataSourceRequest.prototype._request$;
    /**
     * @type {?}
     * @private
     */
    DataSourceRequest.prototype._loading$;
}
/**
 * @abstract
 * @template T
 */
var  /**
 * @abstract
 * @template T
 */
ApiDataSource = /** @class */ (function () {
    function ApiDataSource() {
    }
    return ApiDataSource;
}());
if (false) {
    /**
     * @abstract
     * @param {?} request
     * @return {?}
     */
    ApiDataSource.prototype.handle = function (request) { };
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/api.mapper.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var ApiMapper = /** @class */ (function () {
    function ApiMapper() {
    }
    /**
     * @template T
     * @param {?} data
     * @return {?}
     */
    ApiMapper.prototype.toPageResponse = /**
     * @template T
     * @param {?} data
     * @return {?}
     */
    function (data) {
        return {
            pageSize: (/** @type {?} */ (data['page_size'])),
            pageNumber: (/** @type {?} */ (data['page_number'])),
            totalPages: (/** @type {?} */ (data['total_pages'])),
            totalEntries: (/** @type {?} */ (data['total_entries'])),
            data: (/** @type {?} */ (data['data']))
        };
    };
    /**
     * @param {?} data
     * @return {?}
     */
    ApiMapper.prototype.toPageRequest = /**
     * @param {?} data
     * @return {?}
     */
    function (data) {
        /** @type {?} */
        var params = {};
        params['page'] = "" + (data.pageNumber || 1);
        params['page_size'] = "" + (data.pageSize || 25);
        /** @type {?} */
        var sort = (data.sort || [])
            .map((/**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var name = _a.name;
            return name;
        }))
            .filter((/**
         * @param {?} name
         * @return {?}
         */
        function (name) { return !!name; }))
            .join(',');
        /** @type {?} */
        var sortDirection = (data.sort || [])
            .map((/**
         * @param {?} __0
         * @return {?}
         */
        function (_a) {
            var direction = _a.direction;
            return direction;
        }))
            .filter((/**
         * @param {?} direction
         * @return {?}
         */
        function (direction) { return !!direction; }))
            .join(',');
        if (sort.length > 0 && sortDirection.length > 0) {
            params['sort'] = sort;
            params['sort_direction'] = sortDirection;
        }
        if (data.query && data.query.length > 0 && data.queryFields && data.queryFields.length > 0) {
            params['query'] = data.query;
            params['query_fields'] = data.queryFields.join(',');
        }
        return params;
    };
    return ApiMapper;
}());

/**
 * @fileoverview added by tsickle
 * Generated from: lib/api.service.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var Api = /** @class */ (function () {
    function Api(_http, _mapper, _config) {
        this._http = _http;
        this._mapper = _mapper;
        this._config = _config;
        // Validate the config exists.
        if (!this._config) {
            throw new Error('API configuration was not received properly.');
        }
        // Cache the base url.
        this._baseUrl = this._config.baseUrl;
    }
    /**
     * @template T
     * @param {?} endpoint
     * @param {?=} params
     * @param {?=} options
     * @return {?}
     */
    Api.prototype.page = /**
     * @template T
     * @param {?} endpoint
     * @param {?=} params
     * @param {?=} options
     * @return {?}
     */
    function (endpoint, params, options) {
        var _this = this;
        if (params === void 0) { params = {}; }
        // Compose the params and headers.
        /** @type {?} */
        var pageParams = this._mapper.toPageRequest(params);
        /** @type {?} */
        var extraParams = (options && options.params) || {};
        /** @type {?} */
        var extraHeaders = (options && options.headers) || {};
        // Return an observable so it can be a stream.
        return this.get(endpoint, {
            headers: extraHeaders,
            params: __assign({}, pageParams, extraParams)
        }).pipe(map((/**
         * @param {?} response
         * @return {?}
         */
        function (response) { return _this._mapper.toPageResponse(response); })));
    };
    /**
     * @template T
     * @param {?} endpoint
     * @param {?=} options
     * @return {?}
     */
    Api.prototype.get = /**
     * @template T
     * @param {?} endpoint
     * @param {?=} options
     * @return {?}
     */
    function (endpoint, options) {
        // Add the base url to the endpoint.
        /** @type {?} */
        var url = this.toAbsoluteUrl(endpoint);
        // Return an observable so it can be a stream.
        return this._http.get(url, options);
    };
    /**
     * @template T
     * @param {?} endpoint
     * @param {?=} body
     * @return {?}
     */
    Api.prototype.post = /**
     * @template T
     * @param {?} endpoint
     * @param {?=} body
     * @return {?}
     */
    function (endpoint, body) {
        return __awaiter(this, void 0, void 0, function () {
            var url;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        // Add the base url to the endpoint.
                        url = this.toAbsoluteUrl(endpoint);
                        return [4 /*yield*/, this._http.post(url, body).toPromise()];
                    case 1: 
                    // Execute the post call as a promise.
                    return [2 /*return*/, _a.sent()];
                }
            });
        });
    };
    /**
     * @template T
     * @param {?} endpoint
     * @param {?} body
     * @return {?}
     */
    Api.prototype.put = /**
     * @template T
     * @param {?} endpoint
     * @param {?} body
     * @return {?}
     */
    function (endpoint, body) {
        return __awaiter(this, void 0, void 0, function () {
            var url;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        // Add the base url to the endpoint.
                        url = this.toAbsoluteUrl(endpoint);
                        return [4 /*yield*/, this._http.put(url, body).toPromise()];
                    case 1: 
                    // Execute the put call as a promise.
                    return [2 /*return*/, _a.sent()];
                }
            });
        });
    };
    /**
     * @template T
     * @param {?} endpoint
     * @return {?}
     */
    Api.prototype.delete = /**
     * @template T
     * @param {?} endpoint
     * @return {?}
     */
    function (endpoint) {
        return __awaiter(this, void 0, void 0, function () {
            var url;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        // Add the base url to the endpoint.
                        url = this.toAbsoluteUrl(endpoint);
                        return [4 /*yield*/, this._http.delete(url).toPromise()];
                    case 1: 
                    // Execute the delete call as a promise.
                    return [2 /*return*/, _a.sent()];
                }
            });
        });
    };
    /**
     * @private
     * @param {?} endpoint
     * @return {?}
     */
    Api.prototype.toAbsoluteUrl = /**
     * @private
     * @param {?} endpoint
     * @return {?}
     */
    function (endpoint) {
        return "" + this._baseUrl + endpoint;
    };
    Api.decorators = [
        { type: Injectable }
    ];
    /** @nocollapse */
    Api.ctorParameters = function () { return [
        { type: HttpClient },
        { type: ApiMapper },
        { type: ApiConfig, decorators: [{ type: Optional }] }
    ]; };
    return Api;
}());
if (false) {
    /**
     * @type {?}
     * @private
     */
    Api.prototype._baseUrl;
    /**
     * @type {?}
     * @private
     */
    Api.prototype._http;
    /**
     * @type {?}
     * @private
     */
    Api.prototype._mapper;
    /**
     * @type {?}
     * @private
     */
    Api.prototype._config;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/api.error.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var ApiError = /** @class */ (function () {
    function ApiError(_status, _error) {
        this._status = _status;
        this._error = _error;
    }
    Object.defineProperty(ApiError.prototype, "status", {
        get: /**
         * @return {?}
         */
        function () {
            return this._status;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ApiError.prototype, "error", {
        get: /**
         * @return {?}
         */
        function () {
            return this._error;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @template T
     * @param {?} token
     * @param {?=} delimiter
     * @return {?}
     */
    ApiError.prototype.get = /**
     * @template T
     * @param {?} token
     * @param {?=} delimiter
     * @return {?}
     */
    function (token, delimiter) {
        if (delimiter === void 0) { delimiter = '.'; }
        /** @type {?} */
        var tokens = (token || '').split(delimiter);
        /** @type {?} */
        var result = tokens.reduce((/**
         * @param {?} previous
         * @param {?} token
         * @return {?}
         */
        function (previous, token) {
            if (previous && previous[token]) {
                return previous[token];
            }
            return null;
        }), this._error || {});
        return (/** @type {?} */ (result));
    };
    /**
     * @param {?} token
     * @param {?=} delimiter
     * @return {?}
     */
    ApiError.prototype.has = /**
     * @param {?} token
     * @param {?=} delimiter
     * @return {?}
     */
    function (token, delimiter) {
        if (delimiter === void 0) { delimiter = '.'; }
        return !!this.get(token, delimiter);
    };
    /**
     * @param {?} token
     * @param {?} value
     * @return {?}
     */
    ApiError.prototype.includes = /**
     * @param {?} token
     * @param {?} value
     * @return {?}
     */
    function (token, value) {
        /** @type {?} */
        var array = this.get(token);
        return (array || []).includes(value);
    };
    return ApiError;
}());
if (false) {
    /**
     * @type {?}
     * @private
     */
    ApiError.prototype._status;
    /**
     * @type {?}
     * @private
     */
    ApiError.prototype._error;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/api.module.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var ApiModule = /** @class */ (function () {
    function ApiModule(_parent) {
        if (_parent) {
            throw new Error('ApiModule is already loaded; Import it in the AppModule only.');
        }
    }
    /**
     * @param {?} config
     * @return {?}
     */
    ApiModule.forRoot = /**
     * @param {?} config
     * @return {?}
     */
    function (config) {
        return {
            ngModule: ApiModule,
            providers: [
                { provide: ApiConfig, useValue: config },
                Api
            ]
        };
    };
    ApiModule.decorators = [
        { type: NgModule, args: [{
                    imports: [
                        HttpClientModule
                    ],
                    providers: [
                        { provide: ApiMapper, useClass: ApiMapper }
                    ]
                },] }
    ];
    /** @nocollapse */
    ApiModule.ctorParameters = function () { return [
        { type: ApiModule, decorators: [{ type: Optional }, { type: SkipSelf }] }
    ]; };
    return ApiModule;
}());

/**
 * @fileoverview added by tsickle
 * Generated from: public_api.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * Generated from: bravobit-bb-foundation-api.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

export { Api, ApiConfig, ApiDataSource, ApiError, ApiMapper, ApiModule, DataSourceRequest };
//# sourceMappingURL=bravobit-bb-foundation-api.js.map
