import * as i0 from '@angular/core';
import { Injectable } from '@angular/core';
import * as i1 from '@c8y/client';
import { Service } from '@c8y/client';
import { agentBaseUrl, c8y_lwm2m, LWM2MEndpoint, ValidationType, Mode } from '@c8y/ngx-components/protocol-lwm2m/model';
import { Subject, BehaviorSubject, of, from, throwError } from 'rxjs';
import { switchMap, map, catchError, takeUntil, tap } from 'rxjs/operators';
import * as i2 from '@c8y/ngx-components';
import { gettext } from '@c8y/ngx-components';

class Lwm2mClientService extends Service {
    constructor(client) {
        super(client);
        this.listUrl = 'device';
        this.baseUrl = agentBaseUrl;
    }
    isLwm2mDevice(mo) {
        return (!!mo?.c8y_IsLwm2mDevice || mo?.c8y_DeviceTypes?.includes(c8y_lwm2m) || mo?.type === c8y_lwm2m);
    }
    detail(entityOrId, filter = {}) {
        return super.detail(entityOrId, filter);
    }
    update(entity) {
        return super.update(entity);
    }
    fetch(url, init) {
        return super.fetch(url, init);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mClientService, deps: [{ token: i1.FetchClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mClientService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mClientService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i1.FetchClient }] });

class Lwm2mConfigurationService extends Lwm2mClientService {
    constructor(client, alertService) {
        super(client);
        this.alertService = alertService;
        this.baseUrl = `${agentBaseUrl}/v1`;
        this._destroy$ = new Subject();
        this._listServers$ = new Subject();
        this._servers$ = new BehaviorSubject([]);
        this._settings$ = new BehaviorSubject({});
        this._certificates$ = new BehaviorSubject([]);
        this._securityModeDictRaw$ = new BehaviorSubject([]);
        this._securityModeByScope$ = new BehaviorSubject([]);
        this.servers$ = this._servers$.asObservable();
        this.settings$ = this._settings$.asObservable();
        this.certificates$ = this._certificates$.asObservable();
        this.securityModesByScope$ = this._securityModeByScope$.asObservable();
        this.securityModesRaw$ = this._securityModeDictRaw$.asObservable();
        this._listServers$
            .pipe(switchMap(() => this.listServers$().pipe(map(resp => this._servers$.next(resp?.data)))), catchError(error => {
            this.alertService.addServerFailure(error);
            return of([]);
        }), takeUntil(this._destroy$))
            .subscribe();
    }
    ngOnDestroy() {
        this._destroy$.next();
        this._destroy$.complete();
    }
    getSettingsFor(urlCfg) {
        this.detail$(urlCfg)
            .pipe(map(({ data }) => data), catchError(error => {
            this.alertService.addServerFailure(error);
            return of({});
        }), takeUntil(this._destroy$))
            .subscribe(data => this._settings$.next(data));
    }
    listServers() {
        this._listServers$.next();
    }
    updateConfig(entity, endpoint) {
        this.update$({ ...entity, endpoint })
            .pipe(catchError(error => {
            this.alertService.addServerFailure(error);
            return of(null);
        }), takeUntil(this._destroy$))
            .subscribe();
    }
    onBeforeUpdate(entity) {
        return this.deleteFieldsInRequest(entity);
    }
    onBeforeCreate(entity) {
        return this.deleteFieldsInRequest(entity);
    }
    getDetailUrl(entity) {
        const { endpoint } = entity;
        const id = entity.id ?? '';
        const deviceConfigUrl = `device/${this.deviceId}/configuration`;
        if (!endpoint) {
            throw { data: { message: gettext('Unable to find endpoint') } };
        }
        return id.length > 0 && endpoint === LWM2MEndpoint.servers
            ? `${deviceConfigUrl}/${endpoint}/${id}`
            : `${deviceConfigUrl}/${endpoint}`;
    }
    validate(certificate, type) {
        if (certificate?.length > 0) {
            const body = JSON.stringify({
                [type === ValidationType.PRIVATE_KEY ? 'encodedPrivateKey' : 'encodedCertificate']: certificate
            });
            return this.fetch$(`device/configuration/${type}/validate`, {
                method: 'POST',
                headers: { 'content-type': 'application/json', accept: 'application/json' },
                body
            }).pipe(switchMap(result => from(result.json()).pipe(map(data => data['fingerprint'] || data['commonName']))), catchError((e) => {
                const { message, error } = e?.data;
                this.alertService.addServerFailure({
                    data: { message, exceptionMessage: error }
                });
                return throwError(e);
            }));
        }
    }
    getServerCertificates() {
        this.fetchServerCertificates$()
            .pipe(catchError(error => {
            this.alertService.addServerFailure(error);
            return of([]);
        }), takeUntil(this._destroy$))
            .subscribe();
    }
    fetchServerCertificates$() {
        return this.fetch$('dictionary/server-certificates').pipe(switchMap(result => result.json()), tap(result => {
            this._certificates$.next(result);
        }));
    }
    getSecurityModes() {
        this.fetchSecurityModes$()
            .pipe(catchError(error => {
            // Use this as fallback. There is the possibility that
            // the UI version runs against an agent version without the needed endpoint:
            // 'dictionary/security-modes'
            const { data: { status } } = error;
            status !== 404
                ? this.alertService.addServerFailure(error)
                : this._securityModeDictRaw$.next([
                    {
                        label: Mode.DISABLED,
                        value: Mode.DISABLED,
                        useInBootstrapConnectivity: true,
                        useInServerConnectivity: true
                    },
                    {
                        label: Mode.NO_SEC,
                        value: Mode.NO_SEC,
                        useInBootstrapConnectivity: true,
                        useInServerConnectivity: true
                    },
                    {
                        label: Mode.PSK,
                        value: Mode.PSK,
                        useInBootstrapConnectivity: true,
                        useInServerConnectivity: true
                    },
                    {
                        label: 'X.509',
                        value: Mode.X509,
                        useInBootstrapConnectivity: true,
                        useInServerConnectivity: true
                    }
                ]);
            return of([]);
        }))
            .subscribe();
    }
    fetchSecurityModes$() {
        return this.fetch$('dictionary/security-modes').pipe(switchMap(result => result.json()), map((result) => result.map(({ name, useInBootstrapConnectivity, useInServerConnectivity }) => ({
            label: name.replace('X509', 'X.509'),
            value: name,
            useInBootstrapConnectivity,
            useInServerConnectivity
        }))), tap((result) => {
            this._securityModeDictRaw$.next(result);
        }));
    }
    getSecurityModeByScope(scope) {
        this._securityModeByScope$.next(this._securityModeDictRaw$
            .getValue()
            .filter(({ useInBootstrapConnectivity, useInServerConnectivity }) => (useInBootstrapConnectivity && scope === 'useInBootstrapConnectivity') ||
            (useInServerConnectivity && scope === 'useInServerConnectivity')));
    }
    cleanUpBase64Data(fileReadAsDataURL) {
        const base64RegExp = RegExp(/data:\S+;base64,/gi);
        return fileReadAsDataURL?.length > 0 && base64RegExp.test(fileReadAsDataURL)
            ? fileReadAsDataURL.replace(base64RegExp, '')
            : undefined;
    }
    listServers$() {
        this.listUrl = this.getDetailUrl({ endpoint: LWM2MEndpoint.servers });
        return from(super.list());
    }
    createServer$(server) {
        return from(super.create({ ...server, endpoint: LWM2MEndpoint.servers }));
    }
    deleteServer$(server) {
        return from(super.delete({ ...server, endpoint: LWM2MEndpoint.servers }));
    }
    update$(entity) {
        return from(super.update(entity));
    }
    detail$(urlCfg) {
        return from(super.detail(urlCfg));
    }
    fetch$(url, init) {
        return from(super.fetch(url, init));
    }
    deleteFieldsInRequest(entity) {
        delete entity?.id;
        delete entity?.endpoint;
        delete entity?.deviceInfo;
        return entity;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mConfigurationService, deps: [{ token: i1.FetchClient }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mConfigurationService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mConfigurationService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i1.FetchClient }, { type: i2.AlertService }] });

class LWM2MPostOperationsParametersService extends Lwm2mClientService {
    constructor(client) {
        super(client);
        this.detailUrl = '/postRegistrationOptions';
    }
    get() {
        return super.fetch(this.detailUrl);
    }
    put(data) {
        const headers = { 'content-type': 'application/json', accept: 'application/json' };
        return super.fetch(this.detailUrl, {
            method: 'PUT',
            body: JSON.stringify(data),
            headers: headers
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: LWM2MPostOperationsParametersService, deps: [{ token: i1.FetchClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: LWM2MPostOperationsParametersService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: LWM2MPostOperationsParametersService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i1.FetchClient }] });

class Lwm2mBootstrapParametersService extends Lwm2mClientService {
    constructor(client) {
        super(client);
    }
    detail(id) {
        return super.detail(id);
    }
    update(entity) {
        return super.update(entity);
    }
    onBeforeUpdate(entity) {
        delete entity.id;
        return entity;
    }
    getDetailUrl(entity) {
        return `${this.listUrl}/${super.getEntityId(entity)}/bootstrapParams`;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mBootstrapParametersService, deps: [{ token: i1.FetchClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mBootstrapParametersService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: Lwm2mBootstrapParametersService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i1.FetchClient }] });

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

export { LWM2MPostOperationsParametersService, Lwm2mBootstrapParametersService, Lwm2mClientService, Lwm2mConfigurationService };
//# sourceMappingURL=c8y-ngx-components-protocol-lwm2m-services.mjs.map
