import { FeatureCacheService, hookQueryParamModal, hookDocs } from '@c8y/ngx-components';
import * as i0 from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { TrustedCertificateService, DeviceRegistrationService } from '@c8y/client';
import { gettext } from '@c8y/ngx-components/gettext';

class DeviceEnrolmentService {
    constructor() {
        this.trustedCertificateService = inject(TrustedCertificateService);
        this.deviceRegistrationService = inject(DeviceRegistrationService);
        this.featureCacheService = inject(FeatureCacheService);
    }
    async getRegistrationCode(name) {
        const available = await this.caAvailableAndConfigured();
        if (available) {
            const otp = this.generateSecurePassword();
            const host = window.location.hostname;
            const newDeviceReq = {
                id: name,
                name,
                enrollmentToken: otp,
                type: 'thin-edge.io'
            };
            try {
                await this.deviceRegistrationService.create(newDeviceReq);
            }
            catch (e) {
                const statusCode = e?.status || e?.res?.status;
                const errorType = e?.data?.error || e?.res?.error;
                if (statusCode === 422) {
                    if (errorType === 'devicecontrol/Non Unique Result') {
                        return {
                            error: gettext('Device ID already exists. Please choose a different name.'),
                            statusCode,
                            errorType: 'duplicate'
                        };
                    }
                    if (errorType === 'undefined/validationError') {
                        return {
                            error: gettext('Device ID cannot contain whitespace, slashes or any of (+$:). Please choose a different name.'),
                            statusCode,
                            errorType: 'validation'
                        };
                    }
                }
                throw e;
            }
            return {
                script: `curl -fsSL https://thin-edge.io/trial-linux.sh | sh -s -- --device-id "${name}" --c8y-url "${host}" --one-time-password '${otp}'`,
                docker: `curl -fsSL https://thin-edge.io/trial-linux-docker.sh | sh -s -- --device-id "${name}" --c8y-url "${host}" --one-time-password '${otp}'`
            };
        }
        return { error: gettext('Certificate authority not available.') };
    }
    generateSecurePassword(length = 32) {
        const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+;:,.<>?';
        let password = '';
        const crypto = window.crypto || window.msCrypto;
        const maxValidByte = 256 - (256 % charset.length);
        while (password.length < length) {
            const buffer = new Uint8Array(length - password.length);
            crypto.getRandomValues(buffer);
            for (let i = 0; i < buffer.length && password.length < length; i++) {
                const byte = buffer[i];
                if (byte < maxValidByte) {
                    password += charset[byte % charset.length];
                }
            }
        }
        return password;
    }
    async showQuicklink() {
        return this.featureCacheService.getFeatureStatePromise('certificate-authority');
    }
    async caAvailableAndConfigured() {
        try {
            const shouldShow = await this.featureCacheService.getFeatureStatePromise('certificate-authority');
            if (!shouldShow) {
                return false;
            }
            const { data: certs } = await this.trustedCertificateService.list({
                certificateAuthority: true
            });
            return (certs || []).some(c => c.status === 'ENABLED');
        }
        catch (e) {
            // ignore
            return false;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeviceEnrolmentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeviceEnrolmentService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeviceEnrolmentService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }] });

class DeviceEnrolmentDocLinkFactory {
    constructor(deviceEnrolmentService) {
        this.deviceEnrolmentService = deviceEnrolmentService;
        this.docLinks = null;
    }
    async get() {
        if (this.docLinks === null) {
            const available = await this.deviceEnrolmentService.showQuicklink();
            this.docLinks = available
                ? [
                    {
                        icon: 'c8y-icon-duocolor c8y-icon c8y-icon-icon c8y-icon-device-connect',
                        label: 'Try thin-edge.io',
                        type: 'quicklink',
                        url: '?showConnectDevice=true'
                    }
                ]
                : [];
        }
        return this.docLinks;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeviceEnrolmentDocLinkFactory, deps: [{ token: DeviceEnrolmentService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeviceEnrolmentDocLinkFactory }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeviceEnrolmentDocLinkFactory, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: DeviceEnrolmentService }] });

const deviceEnrolmentProviders = [
    hookQueryParamModal({
        queryParam: 'showConnectDevice',
        loadComponent: () => import('@c8y/ngx-components/device-enrolment/modal').then(m => m.DeviceEnrolmentModalComponent),
        modalConfig: {
            class: 'modal-md',
            ignoreBackdropClick: true,
            keyboard: false
        }
    }),
    hookDocs(DeviceEnrolmentDocLinkFactory)
];

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

export { deviceEnrolmentProviders };
//# sourceMappingURL=c8y-ngx-components-device-enrolment.mjs.map
