import { ɵɵelement, ɵɵnextContext, ɵɵproperty, ɵɵgetCurrentView, ɵɵelementStart, ɵɵlistener, ɵɵrestoreView, ɵɵtext, ɵɵelementEnd, ɵɵclassMap, ɵɵadvance, ɵɵtextInterpolate1, ɵɵtemplate, ɵɵelementContainerStart, ɵɵelementContainerEnd, ɵɵtemplateRefExtractor, ɵɵreference, ɵɵelementContainer, EventEmitter, ɵɵdirectiveInject, ɵɵdefineComponent, ɵsetClassMetadata, Component, Output, Input, ɵɵclassMapInterpolate1, ɵɵtextInterpolate, ɵɵdefineNgModule, ɵɵdefineInjector, ɵɵsetNgModuleScope, NgModule } from '@angular/core';
import { __awaiter } from 'tslib';
import { FormBuilder, NgControlStatusGroup, FormGroupDirective, NgControlStatus, FormControlName, MaxLengthValidator, MinLengthValidator, PatternValidator, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ToastController, IonItem, IonToggle, BooleanValueAccessor, IonText, IonIcon, IonSelect, SelectValueAccessor, IonSelectOption, IonInput, TextValueAccessor, IonButtons, IonButton, IonSpinner, IonGrid, IonRow, IonCol, IonLabel, IonToolbar } from '@ionic/angular';
import { isCodeError } from '@iotize/common/error';
import { TapInfo, PendingCallManager, getFormFieldOrError, LibError, CurrentDeviceService, AutoFocusDirective, LibCommonModule } from '@iotize/ionic';
import { HostProtocol, TargetProtocol, TapResponse, TapError, TapResponseStatusError } from '@iotize/tap';
import { ResultCode } from '@iotize/tap/client/api';
import { StringConverter, tapResponseStatusToString } from '@iotize/tap/client/impl';
import { NfcConnectionPriority, NfcPairingMode } from '@iotize/tap/service/impl/interface';
import { WifiMode } from '@iotize/tap/service/impl/wifi';
import { createDebugger } from '@iotize/common/debug';
import { NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault, NgForOf } from '@angular/common';
import { ConnectionState } from '@iotize/tap/protocol/api';
import { DomElementAccessor } from '@iotize/common/data-accessor';
import { IoTizeStudioToTapConfigConverter } from '@iotize/tap/config/iotize-studio';

const TAP_CONFIG_PATTERN = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/;
const IPV4_PATTERN = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/;
const SSID_PATTERN = /^[^!#;+\]\/"\t][^+\]\/"\t]{0,30}[^ !#;+\]\/"\t]$|^[^ !#;+\]\/"\t]$/;
function regexValidator(pattern) {
    return (control) => {
        const value = control.value;
        return !pattern.test(value)
            ? { invalidFormat: { value: control.value } }
            : null;
    };
}
const validateTapVersion = regexValidator(TAP_CONFIG_PATTERN);
function enumFormatter(data) {
    return (value) => {
        if (Array.isArray(value)) {
            if (value.length === 0) {
                return '-';
            }
            return value.map((key) => HostProtocol[key]).join(', ');
        }
        else {
            return data[value];
        }
    };
}
function isTapConfigured(version) {
    return !(version.major === 0 && version.minor === 0 && version.patch === 0);
}
function enumToOptions(mapping) {
    const keys = Object.keys(mapping).filter((k) => typeof mapping[k] === 'number');
    // console.log('enumToOptions', result);
    return keys.map((key) => {
        return { key: mapping[key], text: key };
    });
}
function stringToEnumArray(v, mapping) {
    return v
        .split(',')
        .map((item) => item.trim())
        .map((item) => {
        if (!(item in mapping)) {
            throw new Error(`Invalid value "${item}". Must one of the following: ${Object.keys(mapping).join(', ')}`);
        }
        return mapping[item];
    });
}
const defaultInfoResolverConfig = [
    {
        key: TapInfo.serialNumber,
        title: 'Serial number',
        description: 'Unique identifier for your Tap',
        editable: false,
        getValue: (tap) => tap.service.device.getSerialNumber(),
    },
    {
        key: TapInfo.modelName,
        title: 'Model name',
        description: "Tap model's name",
        editable: false,
        getValue: (tap) => tap.service.device.getFirmwareFlavor(),
    },
    {
        key: TapInfo.tapManufacturer,
        title: 'Manufacturer',
        description: 'Name of the Tap manufacturer',
        editable: false,
        getValue: (tap) => tap.service.device.getManufacturer(),
    },
    {
        key: TapInfo.HostProtocol,
        title: 'Protocol',
        description: 'Communication protocol between your TapNLink and your application',
        getValue: (tap) => {
            return tap.service.interface.getCurrentHostProtocol();
        },
        putValue: (tap, protocol) => {
            return tap.service.interface.putCurrentHostProtocol(protocol);
        },
        input: {
            type: 'select',
            options: enumToOptions(HostProtocol),
        },
        viewFormatter: enumFormatter(HostProtocol),
    },
    {
        key: TapInfo.appName,
        title: 'Application name',
        description: 'Also used when broadcasting with BLE or Wi-Fi',
        input: {
            maxLength: 32,
        },
        getValue: (tap) => tap.service.interface.getAppName(),
        putValue: (tap, value) => {
            return tap.service.interface.putAppName(value);
        },
    },
    {
        key: TapInfo.configVersion,
        title: 'Tap configuration version',
        description: 'Tap configuration version loaded on your device',
        input: {
            pattern: TAP_CONFIG_PATTERN,
        },
        viewFormatter: (v) => {
            if (v) {
                return `v${v}`;
            }
            else {
                return 'Not configured';
            }
        },
        formValidators: [validateTapVersion],
        editFormatter: {
            read: (input) => {
                const parts = input.split('.');
                return {
                    major: parseInt(parts[0], 10),
                    minor: parseInt(parts[1], 10),
                    patch: parseInt(parts[2], 10),
                };
            },
            write: (v) => {
                return v ? `${v.major}.${v.minor}.${v.patch}` : '0.0.0';
            },
        },
        getValue: (tap) => tap.service.interface.getConfigVersion(),
        putValue: (tap, version) => {
            // const versionNumber = (v.major << 24) | (v.minor << 16) | v.patch;
            // console.log('As version number: ', versionNumber);
            return tap.service.interface.putConfigVersion(version);
        },
    },
    {
        title: 'Minimal transmission period',
        description: 'Used as an indication for mobile application wether or not it should send data log packets to the cloud',
        key: TapInfo.CloudUploadPeriod,
        viewFormatter: (v) => `${v} ms`,
        input: {
            type: 'number',
        },
        getValue: (tap) => tap.service.cloud.getDataLogUploadPeriod(),
        putValue: function (tap, value) {
            return __awaiter(this, void 0, void 0, function* () {
                return tap.service.cloud.putDataLogUploadPeriod(value);
            });
        },
    },
    {
        title: 'MQTT broker',
        description: 'Mqtt broker used for synchronization ',
        key: TapInfo.CloudEndpoint,
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            const hostname = (yield tap.service.mqtt.getBrokerHostname()).body();
            const port = (yield tap.service.mqtt.getBrokerPort()).body();
            return `${hostname}:${port}`;
        }),
        putValue: (tap, value) => __awaiter(void 0, void 0, void 0, function* () {
            const [hostname, port] = value.split(':');
            const setPort = yield tap.service.mqtt.putBrokerPort(port || '1883');
            setPort.successful();
            return tap.service.mqtt.putBrokerHostname(hostname);
        }),
    },
    {
        title: 'Cloud key',
        description: 'Cloud key used for authentification',
        key: TapInfo.CloudKey,
        getValue: (tap) => tap.service.mqtt.getPassword(),
        putValue: (tap, value) => __awaiter(void 0, void 0, void 0, function* () {
            return tap.service.mqtt.putPassword(value);
        }),
    },
    // {
    //     title: 'MQTT endpoint',
    //     description: 'MQTT endpoint used',
    //     key: TapInfo.MqttEndpoint,
    //     input: {
    //         maxLength: 128
    //     },
    //     getValue: async (tap) => {
    //         const hostname = (await tap.service.mqtt.getBrokerHostname()).body();
    //         const port = (await tap.service.mqtt.getBrokerPort()).body();
    //         return `${hostname}:${port}`;
    //     },
    //     putValue: async function (tap: Tap, value: string) {
    //         const [hostname, port] = value.split(':');
    //         await tap.service.mqtt.putBrokerPort(port);
    //         return await tap.service.mqtt.putBrokerHostname(value);
    //     }
    // },
    {
        title: 'MQTT broker hostname',
        description: 'MQTT broker hostname (for exemple user.cloud.iotize.com)',
        key: TapInfo.MqttBrokerHostname,
        input: {
            maxLength: 128,
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () { return tap.service.mqtt.getBrokerHostname(); }),
        putValue: (tap, value) => __awaiter(void 0, void 0, void 0, function* () { return tap.service.mqtt.putBrokerHostname(value); }),
    },
    {
        title: 'MQTT broker port',
        description: 'MQTT broker port (for exemple 1883 or 8883)',
        key: TapInfo.MqttBrokerPort,
        input: {
            maxLength: 128,
            type: 'number',
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () { return tap.service.mqtt.getBrokerPort(); }),
        putValue: (tap, value) => __awaiter(void 0, void 0, void 0, function* () { return tap.service.mqtt.putBrokerPort(value.toString()); }),
    },
    {
        title: 'MQTT password',
        description: 'Mqtt password',
        key: TapInfo.MqttPassword,
        input: {
            maxLength: 32,
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            return (yield tap.service.mqtt.getPassword()).body();
        }),
        putValue: function (tap, value) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield tap.service.mqtt.putPassword(value);
            });
        },
    },
    {
        title: 'MQTT relay net key',
        description: 'Mqtt relay net key',
        key: TapInfo.MqttRelayNetKey,
        input: {
            maxLength: 32,
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            return (yield tap.service.mqtt.getRelayNetKey()).body();
        }),
        putValue: function (tap, value) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield tap.service.mqtt.putRelayNetKey(value);
            });
        },
    },
    // {
    //     title: 'MQTT service name',
    //     description: 'MQTT service name',
    //     key: TapInfo.MqttServiceName,
    //     input: {
    //         maxLength: 32
    //     },
    //     getValue: async (tap) => {
    //         return (await tap.service.mqtt.getBrokerPort()).body();
    //     },
    //     putValue: async function (tap: Tap, value: string) {
    //         return await tap.service.mqtt.putBrokerPort(value);
    //     }
    // },
    {
        title: 'MQTT client id',
        description: 'Unique identifier of the client. Can be anything you want but it must be uniq. \
        Only one client with the same id can be connected at the same time',
        key: TapInfo.MqttClientId,
        input: {
            maxLength: 32,
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            return (yield tap.service.mqtt.getClientId()).body();
        }),
        putValue: function (tap, value) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield tap.service.mqtt.putClientId(value);
            });
        },
    },
    {
        title: 'MQTT password',
        description: 'MQTT password',
        input: {
            maxLength: 128,
        },
        key: TapInfo.MqttPassword,
        getValue: (tap) => {
            return tap.service.mqtt.getPassword();
        },
        putValue: (tap, val) => {
            return tap.service.mqtt.putPassword(val);
        },
    },
    {
        title: 'MQTT username',
        description: 'MQTT username',
        input: {
            maxLength: 32,
        },
        key: TapInfo.MqttUsername,
        getValue: (tap) => {
            return tap.service.mqtt.getUsername();
        },
        putValue: (tap, val) => {
            return tap.service.mqtt.putUsername(val);
        },
    },
    {
        title: 'NFC priority',
        description: 'Enable if NFC has priority over other protocols. \
        It means that a new NFC connection will force disconnection of other connected clients. ',
        input: {
            type: 'toggle',
        },
        key: TapInfo.NFCConnectionPriority,
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            const value = (yield tap.service.interface.getNfcConnectionPriority()).body();
            return value === NfcConnectionPriority.NFC_PRIORITY;
        }),
        putValue: (tap, val) => {
            const mode = val
                ? NfcConnectionPriority.NFC_NON_PRIORITY
                : NfcConnectionPriority.NFC_PRIORITY;
            return tap.service.interface.putNfcConnectionPriority(mode);
        },
    },
    {
        title: 'NFC mandatory to connect to the Tap',
        description: 'Choose whether or not NFC must be used to connect to the Tap. ',
        input: {
            type: 'select',
            options: [
                {
                    key: NfcPairingMode.NO,
                    text: 'No',
                },
                {
                    key: NfcPairingMode.MANDATORY,
                    text: 'Yes',
                },
                {
                    key: NfcPairingMode.MANDATORY_FOR_LOGIN,
                    text: 'Only to login',
                },
            ],
        },
        key: TapInfo.NFCPairingMode,
        getValue: (tap) => {
            return tap.service.interface.getNfcPairingMode();
        },
        putValue: (tap, val) => {
            return tap.service.interface.putNfcPairingMode(val);
        },
    },
    {
        title: 'Packet count',
        description: 'The current number of data log packet in memory',
        key: TapInfo.DataLogPacketCount,
        getValue: (tap) => tap.service.dataLog.getPacketCount(),
    },
    {
        title: 'Maximum packet count',
        description: 'Maximum number of data log packet the Tap is able to store',
        key: TapInfo.DataLogMaxPacketCount,
        viewFormatter: (v) => {
            return v === 0 ? 'NO LIMIT' : v.toString();
        },
        input: {
            type: 'number',
        },
        getValue: (tap) => tap.service.dataLog.getMaxPacketCount(),
    },
    {
        title: 'Target connected',
        description: 'Wether or not Tap is connected to the target application',
        key: TapInfo.IsTargetConnected,
        // viewFormatter: (v: boolean) => v ? 'YES' : 'NO',
        getValue: (tap) => tap.service.target.isConnected(),
        putValue: (tap, enabled) => {
            if (enabled) {
                return tap.service.target.connect();
            }
            else {
                return tap.service.target.disconnect();
            }
        },
        input: {
            type: 'toggle',
        },
    },
    {
        title: 'Universal link',
        description: 'Will be used for iOS app',
        key: TapInfo.universalLink,
        icon: 'link',
        getValue: (tap) => tap.service.interface.getUniversalLink(),
        putValue: (tap, value) => {
            return tap.service.interface.putUniversalLink(value);
        },
    },
    {
        title: 'Android application record',
        description: 'For example "com.iotize.app.tapmanager"',
        key: TapInfo.androidApplicationRecord,
        // TODO replace with getAndroidApplicationId()
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            const appPath = (yield tap.service.interface.getAppPath()).body();
            if (appPath.startsWith('$4/')) {
                return appPath.substring(3);
            }
            else {
                return false;
            }
        }),
        putValue: (tap, value) => __awaiter(void 0, void 0, void 0, function* () {
            return tap.service.interface.putAppPath(`$4/${value}`);
        }),
    },
    {
        title: 'Encryption',
        description: 'If enabled, it will use encryption for communication between the mobile device \
        (smartphone, PC, ...) and your TapNLink',
        key: TapInfo.useEncryption,
        input: {
            type: 'toggle',
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            const lockOptions = (yield tap.service.interface.getSecurityOptions()).body();
            return lockOptions.scramActivated;
        }),
    },
    {
        title: 'Encryption iteration number',
        description: 'Number of iteration for encryption algorithm. Higher it is, the more secure it gets',
        key: TapInfo.scramIterationNumber,
        input: {
            type: 'number',
            min: 0,
            max: 0xffff,
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            return (yield tap.service.scram.getHashIteration()).body();
        }),
    },
    {
        title: 'Authorized hardware factory reset',
        description: 'If enabled, user can perform a hardware factory reset',
        key: TapInfo.lockFactoryReset,
        input: {
            type: 'toggle',
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            const lockOptions = (yield tap.service.interface.getSecurityOptions()).body();
            return !lockOptions.disableHardwareFactoryReset;
        }),
    },
    {
        title: 'Use password hash',
        description: 'If true, user passwords will be stored as hash',
        key: TapInfo.hashPassword,
        input: {
            type: 'toggle',
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            const lockOptions = (yield tap.service.interface.getSecurityOptions()).body();
            return lockOptions.hashPassword;
        }),
    },
    {
        title: 'Authorize login with UID',
        description: 'If enabled, it will authorized a user to log in as an administrator using a unique identifier',
        key: TapInfo.isLoginWithUIDEnabled,
        input: {
            type: 'toggle',
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            const lockOptions = (yield tap.service.interface.getSecurityOptions()).body();
            return !lockOptions.disableLoginWithUID;
        }),
    },
    {
        title: 'Authorize factory reset using LWM2M',
        description: 'If enabled, it will authorized an administrator user to do a factory reset using the API',
        key: TapInfo.isLWM2MFactoryResetEnabled,
        input: {
            type: 'toggle',
        },
        getValue: (tap) => __awaiter(void 0, void 0, void 0, function* () {
            const lockOptions = (yield tap.service.interface.getSecurityOptions()).body();
            return !lockOptions.disableResourceFactoryReset;
        }),
    },
    {
        title: 'Security options',
        description: 'Security options',
        key: TapInfo.lockOptions,
        putValue: (tap, value) => {
            return tap.service.interface.putSecurityOptions(value);
        },
        getValue: (tap) => {
            return tap.service.interface.getSecurityOptions();
        },
    },
    {
        title: 'Application path',
        description: 'Contains the path to the application to load when connecting to this device. It may be an application id or a website URL.',
        key: TapInfo.appPath,
        putValue: (tap, value) => {
            return tap.service.interface.putAppPath(value);
        },
        getValue: (tap) => tap.service.interface.getAppPathResolved(),
    },
    {
        title: 'Username',
        description: 'Username used for login',
        key: TapInfo.ProfileName,
        getValue: (tap, groupId) => {
            return tap.service.group.getName(groupId);
        },
        putValue: (tap, value, groupId) => {
            return tap.service.group.putName(groupId, value);
        },
    },
    {
        title: 'Parent group ID',
        description: 'Identifier of group from where this user inherits his rights',
        key: TapInfo.parentGroupId,
        getValue: (tap, groupId) => {
            return tap.service.group.getAlias(groupId);
        },
        putValue: (tap, value, groupId) => {
            return tap.service.group.putAlias(groupId, value);
        },
    },
    {
        title: 'Clear data log packet store',
        description: 'This action cannot be undone',
        getValue: false,
        key: TapInfo.DataLogClearPacketStore,
        actions: [
            {
                title: 'Clear',
                icon: 'trash',
                call: (tap) => {
                    return tap.service.dataLog.flush();
                },
            },
        ],
    },
    {
        title: 'Session life time',
        description: 'Duration of the session in seconds (it does not apply right away, it will only be used on following logins)',
        key: TapInfo.ProfileSessionLifeTime,
        getValue: (tap, groupId) => {
            return tap.service.group.getSessionLifetime(groupId);
        },
        putValue: (tap, value, groupId) => {
            return tap.service.group.putSessionLifetime(groupId, value);
        },
    },
    {
        title: 'Target protocol',
        description: 'Communication protocol used between the Tap and the micro controller',
        key: TapInfo.TargetProtocol,
        getValue: (tap) => {
            return tap.service.target.getProtocol();
        },
        putValue: (tap, protocol) => {
            return tap.service.target.putProtocol(protocol);
        },
        // TODO
        setValue: (tap, protocol) => {
            return tap.service.target.setProtocol(protocol);
        },
        viewFormatter: enumFormatter(TargetProtocol),
        input: {
            type: 'select',
            options: enumToOptions(TargetProtocol).filter((f) => {
                return f.key !== TargetProtocol.JTAG;
            }),
        },
    },
    {
        title: 'Available protocols',
        description: 'Communication protocols available on your device',
        key: TapInfo.availableHostProtocols,
        viewFormatter: enumFormatter(HostProtocol),
        editFormatter: {
            write: (v) => {
                // console.log('Host protocols: ', v);
                if (!v || v.length === 0) {
                    return 'NONE';
                }
                return v.map((key) => HostProtocol[key]).join(', ');
            },
            read: (v) => {
                return stringToEnumArray(v, HostProtocol);
            },
        },
        getValue: (tap) => tap.service.interface.getAvailableHostProtocols(),
    },
    {
        title: 'Authorized protocols',
        description: 'Communication protocols authorized on your device',
        key: TapInfo.authorizedHostProtocols,
        input: {
            type: 'select',
            multiple: true,
            options: [],
        },
        viewFormatter: enumFormatter(HostProtocol),
        // (v: HostProtocol[]) => {
        //     if (!v || v.length == 0) {
        //         return 'NONE'
        //     }
        //     return v.map(key => HostProtocol[key]).join(', ');
        // },
        // editFormatter: {
        //     write: (v: HostProtocol[]): string => {
        //         if (!v || v.length == 0) {
        //             return 'NONE'
        //         }
        //         return v.map(key => HostProtocol[key]).join(', ');
        //     },
        //     read: (v: string): HostProtocol[] => {
        //         let protocols: HostProtocol[] = stringToEnumArray<HostProtocol>(v, HostProtocol);
        //         return protocols;
        //     }
        // },
        getValue: (tap) => tap.service.interface.getAuthorizedHostProtocol(),
        putValue: (tap, protocols) => {
            return tap.service.interface.putAuthorizedHostProtocol(protocols);
        },
        init: (service, config) => __awaiter(void 0, void 0, void 0, function* () {
            const hostProtocols = yield service.getValue(TapInfo.availableHostProtocols);
            if (config.input !== undefined) {
                config.input.options = hostProtocols.map((key) => {
                    return { key: key, text: HostProtocol[key] };
                });
            }
        }),
    },
    {
        title: 'Enable/Disable data log acquisition on your device',
        key: TapInfo.DataLogToggleAcquisition,
        getValue: (tap) => {
            return tap.service.dataLog.isRunning();
        },
        actions: [
            {
                title: 'start',
                icon: 'play',
                color: 'primary',
                call: (tap) => tap.service.dataLog.run(),
                triggersRefresh: [TapInfo.DatalogAcquisitionRunning],
            },
            {
                title: 'stop',
                icon: 'pause',
                color: 'danger',
                call: (tap) => tap.service.dataLog.stop(),
                triggersRefresh: [TapInfo.DatalogAcquisitionRunning],
            },
        ],
    },
    {
        key: TapInfo.BundleDatalogPeriod,
        title: 'Data log acquisition period',
        description: 'Define variable value acquisition period (in milliseconds)',
        input: {
            type: 'number',
        },
        getValue: function (tap, bundleId) {
            if (bundleId === undefined) {
                throw new Error('Missing parameter bundleId');
            }
            return tap.service.bundle.getDataLogPeriod(bundleId);
        },
        putValue: (tap, value, bundleId) => {
            if (bundleId === undefined) {
                throw new Error('Missing parameter bundleId');
            }
            return tap.service.bundle.putDataLogPeriod(bundleId, value);
        },
    },
    {
        key: TapInfo.configPath,
        getValue: (tap) => tap.service.interface.getConfigPath(),
        title: 'Configuration file path',
    },
    // {
    //     key: TapInfo.isTapConfigured,
    //     title: 'Tap is configured',
    //     input: {
    //         type: 'toggle'
    //     },
    //     getValue: async function (tap: Tap) {
    //         let version = (await tap.service.interface.getConfigVersion()).body();
    //         return !(version.major == 0 && version.minor == 0 && version.patch == 0);
    //     },
    //     editable: false
    // },
    {
        key: TapInfo.tapFirmwareVersion,
        title: 'Tap firmware version',
        description: 'IoTize Tap firmware version currently loaded on the Tap',
        getValue: (tap) => tap.service.device.getFirmwareVersion(),
    },
    {
        key: TapInfo.DatalogAcquisitionRunning,
        getValue: (tap) => tap.service.dataLog.isRunning(),
        title: 'Data log acquision running',
        description: 'Is data log acquisition running',
    },
    {
        key: TapInfo.AdpStats,
        title: 'ADP info',
        getValue: (tap) => tap.service.tapnpass.getStatus(),
    },
    {
        key: TapInfo.AdpVersion,
        title: 'ADP version',
        getValue: (tap) => tap.service.tapnpass.getStatus(),
        viewFormatter: (stats) => {
            const v = stats.header.version;
            return `${v.major}.${v.minor}.${v.patch}`;
        },
        editable: false,
    },
    {
        key: TapInfo.SinglePacketInfo,
        title: 'Single packet info',
        getValue: (tap) => {
            return tap.service.singlePacket.getInfo();
        },
    },
    {
        key: TapInfo.protocolHostInactivityPeriod,
        title: 'Disconnection inactivity delay',
        description: 'Duration (in seconds) after which the Tap will disconnect the connected client if there is no communication',
        input: {
            type: 'number',
            min: 0,
            max: 255,
        },
        getValue: (tap) => {
            return tap.service.interface.getHostInactivityPeriod();
        },
        putValue: (tap, value) => {
            return tap.service.interface.putHostInactivityPeriod(value);
        },
    },
    {
        key: TapInfo.bleMacAddress,
        title: 'BLE Mac address',
        description: 'For example: "C4:A2:EF:45:23"',
        editable: false,
        getValue: (tap) => {
            return tap.service.ble.getAddress();
        },
    },
    {
        key: TapInfo.WifiHostname,
        title: 'Current Tap IP/Hostname',
        description: 'IPV4 address',
        editable: false,
        getValue: (tap) => {
            return tap.service.wifi.getHostname();
        },
        viewFormatter: (v) => {
            if (v === '0.0.0.0') {
                return 'NO IP';
            }
            return v;
        },
    },
    {
        key: TapInfo.WifiSSID,
        title: 'Wi-Fi SSID',
        description: 'Wifi SSID (Service Set IDentifier)',
        editable: false,
        input: {
            minLength: 1,
            maxLength: 32,
        },
        formValidators: [regexValidator(SSID_PATTERN)],
        getValue: (tap) => {
            return tap.service.wifi.getSSID();
        },
        putValue: (tap, value) => {
            return tap.service.wifi.putSSID(value);
        },
    },
    {
        key: TapInfo.NetworkInfraIp,
        title: 'Wi-Fi IP',
        description: 'Use ip address 0.0.0.0 if you want to let Tap use DHCP to obtain an IP address',
        getValue: (tap) => tap.service.wifi.getIp(),
        putValue: (tap, value) => tap.service.wifi.putIp(value),
        formValidators: [regexValidator(IPV4_PATTERN)],
        viewFormatter: (value) => {
            if (value === '0.0.0.0') {
                return 'Dynamic (DHCP)';
            }
            return value;
        },
    },
    {
        key: TapInfo.NetworkGatewayIp,
        title: 'Wi-Fi gateway IP address',
        getValue: (tap) => tap.service.wifi.getGatewayIp(),
        formValidators: [regexValidator(IPV4_PATTERN)],
    },
    {
        key: TapInfo.WifiMode,
        title: 'Wi-Fi mode',
        description: 'Your Tap can either connect to an existing Wi-Fi network or behave as a network',
        editable: false,
        input: {
            type: 'select',
            // options: enumToOptions(WifiMode),
            options: [
                {
                    icon: 'git-network',
                    key: WifiMode.NETWORK,
                    text: 'Network',
                },
                {
                    icon: 'people',
                    key: WifiMode.PEER_TO_PEER,
                    text: 'Access point',
                },
            ],
        },
        getValue: (tap) => {
            return tap.service.wifi.getMode();
        },
        putValue: (tap, value) => {
            return tap.service.wifi.putMode(value);
        },
    },
    {
        key: TapInfo.isHostProtocolAuthorized,
        title: 'Authorized',
        description: 'Enable to authorized the given protocol to be used to connect to this device',
        editable: false,
        input: {
            type: 'toggle',
        },
        getValue: (tap, protocol) => __awaiter(void 0, void 0, void 0, function* () {
            if (protocol === undefined) {
                throw new Error('Illegal argument error: missing protocol');
            }
            const protocols = (yield tap.service.interface.getAuthorizedHostProtocol()).body();
            return protocols.find((p) => p === protocol) !== undefined;
        }),
        putValue: (tap, value, protocol) => __awaiter(void 0, void 0, void 0, function* () {
            const protocols = (yield tap.service.interface.getAuthorizedHostProtocol()).body();
            if (protocol === undefined) {
                throw new Error('Illegal argument error: missing protocol');
            }
            const indexOfProtocol = protocols.findIndex((p) => p === protocol);
            if (value) {
                if (indexOfProtocol === -1) {
                    protocols.push(protocol);
                }
            }
            else {
                if (indexOfProtocol >= 0) {
                    protocols.splice(indexOfProtocol, 1);
                }
            }
            return tap.service.interface.putAuthorizedHostProtocol(protocols);
        }),
    },
    {
        key: TapInfo.WifiKey,
        title: 'Wi-Fi key',
        description: 'Wi-Fi key',
        editable: false,
        input: {
            type: 'password',
            minLength: 8,
            maxLength: 128,
        },
        getValue: (tap) => {
            return tap.service.wifi.getKey();
        },
        putValue: (tap, value) => {
            return tap.service.wifi.putKey(value);
        },
    },
    {
        key: TapInfo.bundleName,
        title: 'Bundle name',
        description: 'Friendly bundle name to display',
        editable: false,
        input: {
            minLength: 1,
            maxLength: 16,
        },
        getValue: (tap, bundleId) => {
            return tap.service.bundle.getName(bundleId);
        },
        putValue: (tap, value, bundleId) => {
            return tap.service.bundle.putName(bundleId, value);
        },
    },
    {
        key: TapInfo.variableMetaData,
        title: 'Variable meta name',
        description: 'Additional variable data',
        editable: false,
        input: {},
        getValue: (tap, variableId) => __awaiter(void 0, void 0, void 0, function* () {
            const metaData = (yield tap.service.variable.getRawMeta(variableId)).body();
            return StringConverter.ascii().decode(metaData);
        }),
        putValue: (tap, value, bundleId) => {
            const data = StringConverter.ascii().encode(value);
            return tap.service.variable.putRawMeta(bundleId, data);
        },
    },
    {
        key: TapInfo.profilePassword,
        title: 'User password',
        description: 'New user password',
        editable: false,
        input: {
            type: 'password',
            minLength: 1,
            maxLength: 16,
        },
        viewFormatter: () => {
            return '********';
        },
        putValue: (tap, value, profileId) => __awaiter(void 0, void 0, void 0, function* () {
            yield tap.auth.changePassword(value, profileId);
            return TapResponse.SUCCESS(); // TODO fix
        }),
    },
];

const debug = createDebugger('@iotize/ionic:config');

function TapConfigItemComponent_ion_item_0_ion_toggle_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelement(0, "ion-toggle", 6);
} if (rf & 2) {
    const ctx_r2 = ɵɵnextContext(2);
    ɵɵproperty("disabled", !ctx_r2.editMode || ctx_r2.loading || !!ctx_r2.pendingEditCall);
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ion_text_1_Template(rf, ctx) { if (rf & 1) {
    const _r14 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-text", 11);
    ɵɵlistener("click", function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ion_text_1_Template_ion_text_click_0_listener() { ɵɵrestoreView(_r14); const ctx_r13 = ɵɵnextContext(4); return ctx_r13.onValueClick(); });
    ɵɵelement(1, "ion-icon", 12);
    ɵɵtext(2);
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r10 = ɵɵnextContext(4);
    ɵɵclassMap(ctx_r10.editable ? "cell" : "");
    ɵɵadvance(2);
    ɵɵtextInterpolate1(" ", ctx_r10.readError.message, " ");
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_div_1_ion_icon_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelement(0, "ion-icon", 19);
} if (rf & 2) {
    const ctx_r17 = ɵɵnextContext(6);
    ɵɵproperty("name", ctx_r17.selectedOption == null ? null : ctx_r17.selectedOption.icon);
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_div_1_Template(rf, ctx) { if (rf & 1) {
    const _r19 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "div", 16);
    ɵɵlistener("click", function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_div_1_Template_div_click_0_listener() { ɵɵrestoreView(_r19); const ctx_r18 = ɵɵnextContext(5); return ctx_r18.onValueClick(); });
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_div_1_ion_icon_1_Template, 1, 1, "ion-icon", 17);
    ɵɵelementStart(2, "ion-text", 18);
    ɵɵtext(3);
    ɵɵelementEnd();
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r15 = ɵɵnextContext(5);
    ɵɵclassMap(ctx_r15.editable ? "cell" : "");
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r15.selectedOption == null ? null : ctx_r15.selectedOption.icon);
    ɵɵadvance(2);
    ɵɵtextInterpolate1(" ", ctx_r15.displayedValue, " ");
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_ion_text_2_Template(rf, ctx) { if (rf & 1) {
    const _r21 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-text", 20);
    ɵɵlistener("click", function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_ion_text_2_Template_ion_text_click_0_listener() { ɵɵrestoreView(_r21); const ctx_r20 = ɵɵnextContext(5); return ctx_r20.onValueClick(); });
    ɵɵtext(1);
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r16 = ɵɵnextContext(5);
    ɵɵclassMap(ctx_r16.editable ? "cell" : "");
    ɵɵadvance(1);
    ɵɵtextInterpolate1(" ", ctx_r16.displayedValue, " ");
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementContainerStart(0, 13);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_div_1_Template, 4, 4, "div", 14);
    ɵɵtemplate(2, TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_ion_text_2_Template, 2, 3, "ion-text", 15);
    ɵɵelementContainerEnd();
} if (rf & 2) {
    const ctx_r12 = ɵɵnextContext(4);
    ɵɵproperty("ngSwitch", ctx_r12.inputOptions.type);
    ɵɵadvance(1);
    ɵɵproperty("ngSwitchCase", "select");
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementContainerStart(0);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ion_text_1_Template, 3, 3, "ion-text", 9);
    ɵɵtemplate(2, TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_ng_template_2_Template, 3, 2, "ng-template", null, 10, ɵɵtemplateRefExtractor);
    ɵɵelementContainerEnd();
} if (rf & 2) {
    const _r11 = ɵɵreference(3);
    const ctx_r7 = ɵɵnextContext(3);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r7.readError)("ngIfElse", _r11);
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_select_1_ion_select_option_1_ion_icon_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelement(0, "ion-icon", 19);
} if (rf & 2) {
    const option_r25 = ɵɵnextContext().$implicit;
    ɵɵproperty("name", option_r25.icon);
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_select_1_ion_select_option_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementStart(0, "ion-select-option", 25);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_select_1_ion_select_option_1_ion_icon_1_Template, 1, 1, "ion-icon", 17);
    ɵɵtext(2);
    ɵɵelementEnd();
} if (rf & 2) {
    const option_r25 = ctx.$implicit;
    ɵɵproperty("value", option_r25.key);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", option_r25.icon);
    ɵɵadvance(1);
    ɵɵtextInterpolate1(" ", option_r25.text, " ");
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_select_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementStart(0, "ion-select", 23);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_select_1_ion_select_option_1_Template, 3, 3, "ion-select-option", 24);
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r22 = ɵɵnextContext(4);
    ɵɵproperty("multiple", ctx_r22.inputOptions.multiple);
    ɵɵadvance(1);
    ɵɵproperty("ngForOf", ctx_r22.inputOptions.options);
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_input_2_Template(rf, ctx) { if (rf & 1) {
    const _r29 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-input", 26);
    ɵɵlistener("keydown.enter", function TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_input_2_Template_ion_input_keydown_enter_0_listener($event) { ɵɵrestoreView(_r29); const ctx_r28 = ɵɵnextContext(4); return ctx_r28.submit($event); })("keydown.escape", function TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_input_2_Template_ion_input_keydown_escape_0_listener($event) { ɵɵrestoreView(_r29); const ctx_r30 = ɵɵnextContext(4); return ctx_r30.cancelEdit($event); });
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r23 = ɵɵnextContext(4);
    ɵɵproperty("disabled", !!ctx_r23.pendingEditCall)("maxlength", ctx_r23.inputOptions.maxLength)("minlength", ctx_r23.inputOptions.minLength)("max", ctx_r23.inputOptions.max)("min", ctx_r23.inputOptions.min)("pattern", ctx_r23.inputOptions.pattern)("placeholder", ctx_r23.placeholder)("type", ctx_r23.inputOptions.type);
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementContainerStart(0, 13);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_select_1_Template, 2, 2, "ion-select", 21);
    ɵɵtemplate(2, TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_ion_input_2_Template, 1, 8, "ion-input", 22);
    ɵɵelementContainerEnd();
} if (rf & 2) {
    const ctx_r9 = ɵɵnextContext(3);
    ɵɵproperty("ngSwitch", ctx_r9.inputOptions.type);
    ɵɵadvance(1);
    ɵɵproperty("ngSwitchCase", "select");
} }
function TapConfigItemComponent_ion_item_0_ng_template_2_Template(rf, ctx) { if (rf & 1) {
    ɵɵtemplate(0, TapConfigItemComponent_ion_item_0_ng_template_2_ng_container_0_Template, 4, 2, "ng-container", 7);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ng_template_2_ng_template_1_Template, 3, 2, "ng-template", null, 8, ɵɵtemplateRefExtractor);
} if (rf & 2) {
    const _r8 = ɵɵreference(2);
    const ctx_r4 = ɵɵnextContext(2);
    ɵɵproperty("ngIf", !ctx_r4.editMode)("ngIfElse", _r8);
} }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_ion_button_1_Template(rf, ctx) { if (rf & 1) {
    const _r39 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-button", 33);
    ɵɵlistener("click", function TapConfigItemComponent_ion_item_0_ion_buttons_4_ion_button_1_Template_ion_button_click_0_listener() { ɵɵrestoreView(_r39); const ctx_r38 = ɵɵnextContext(3); return ctx_r38.explainPendingCall(); });
    ɵɵelement(1, "ion-icon", 12);
    ɵɵelementEnd();
} if (rf & 2) {
    ɵɵproperty("disabled", false);
} }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_container_2_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementContainer(0);
} }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_0_Template(rf, ctx) { if (rf & 1) {
    const _r44 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-button", 16);
    ɵɵlistener("click", function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_0_Template_ion_button_click_0_listener() { ɵɵrestoreView(_r44); const ctx_r43 = ɵɵnextContext(4); return ctx_r43.editMode = true; });
    ɵɵelement(1, "ion-icon", 35);
    ɵɵelementEnd();
} }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_1_Template(rf, ctx) { if (rf & 1) {
    const _r46 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-button", 36);
    ɵɵlistener("click", function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_1_Template_ion_button_click_0_listener($event) { ɵɵrestoreView(_r46); const ctx_r45 = ɵɵnextContext(4); return ctx_r45.submit($event); });
    ɵɵelement(1, "ion-icon", 37);
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r41 = ɵɵnextContext(4);
    ɵɵproperty("disabled", ctx_r41.loading || ctx_r41.pendingEditCall);
} }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_2_Template(rf, ctx) { if (rf & 1) {
    const _r48 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-button", 36);
    ɵɵlistener("click", function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_2_Template_ion_button_click_0_listener() { ɵɵrestoreView(_r48); const ctx_r47 = ɵɵnextContext(4); return ctx_r47.cancelEdit(); });
    ɵɵelement(1, "ion-icon", 38);
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r42 = ɵɵnextContext(4);
    ɵɵproperty("disabled", ctx_r42.loading);
} }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_Template(rf, ctx) { if (rf & 1) {
    ɵɵtemplate(0, TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_0_Template, 2, 0, "ion-button", 34);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_1_Template, 2, 1, "ion-button", 32);
    ɵɵtemplate(2, TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_ion_button_2_Template, 2, 1, "ion-button", 32);
} if (rf & 2) {
    const ctx_r34 = ɵɵnextContext(3);
    ɵɵproperty("ngIf", !ctx_r34.editMode && ctx_r34.info.putValue);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r34.editMode && !ctx_r34.pendingEditCall);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r34.editMode);
} }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_5_Template(rf, ctx) { }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_ion_button_7_Template(rf, ctx) { if (rf & 1) {
    const _r50 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-button", 36);
    ɵɵlistener("click", function TapConfigItemComponent_ion_item_0_ion_buttons_4_ion_button_7_Template_ion_button_click_0_listener() { ɵɵrestoreView(_r50); const ctx_r49 = ɵɵnextContext(3); return ctx_r49.refreshValue(); });
    ɵɵelement(1, "ion-icon", 39);
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r37 = ɵɵnextContext(3);
    ɵɵproperty("disabled", ctx_r37.loading);
} }
function TapConfigItemComponent_ion_item_0_ion_buttons_4_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementStart(0, "ion-buttons", 27);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ion_buttons_4_ion_button_1_Template, 2, 1, "ion-button", 28);
    ɵɵtemplate(2, TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_container_2_Template, 1, 0, "ng-container", 29);
    ɵɵtemplate(3, TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_3_Template, 3, 3, "ng-template", null, 30, ɵɵtemplateRefExtractor);
    ɵɵtemplate(5, TapConfigItemComponent_ion_item_0_ion_buttons_4_ng_template_5_Template, 0, 0, "ng-template", null, 31, ɵɵtemplateRefExtractor);
    ɵɵtemplate(7, TapConfigItemComponent_ion_item_0_ion_buttons_4_ion_button_7_Template, 2, 1, "ion-button", 32);
    ɵɵelementEnd();
} if (rf & 2) {
    const _r33 = ɵɵreference(4);
    const _r35 = ɵɵreference(6);
    const ctx_r5 = ɵɵnextContext(2);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r5.pendingEditCall);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r5.editable)("ngIfThen", _r33)("ngIfElse", _r35);
    ɵɵadvance(5);
    ɵɵproperty("ngIf", ctx_r5.refresh && ctx_r5.info.getValue && !ctx_r5.editMode);
} }
function TapConfigItemComponent_ion_item_0_ion_spinner_5_Template(rf, ctx) { if (rf & 1) {
    ɵɵelement(0, "ion-spinner", 27);
} }
function TapConfigItemComponent_ion_item_0_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementStart(0, "ion-item", 2);
    ɵɵtemplate(1, TapConfigItemComponent_ion_item_0_ion_toggle_1_Template, 1, 1, "ion-toggle", 3);
    ɵɵtemplate(2, TapConfigItemComponent_ion_item_0_ng_template_2_Template, 3, 2, "ng-template", null, 4, ɵɵtemplateRefExtractor);
    ɵɵtemplate(4, TapConfigItemComponent_ion_item_0_ion_buttons_4_Template, 8, 5, "ion-buttons", 5);
    ɵɵtemplate(5, TapConfigItemComponent_ion_item_0_ion_spinner_5_Template, 1, 0, "ion-spinner", 5);
    ɵɵelementEnd();
} if (rf & 2) {
    const _r3 = ɵɵreference(3);
    const ctx_r0 = ɵɵnextContext();
    ɵɵproperty("formGroup", ctx_r0.form)("lines", ctx_r0.editable ? "" : "none");
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r0.inputOptions.type === "toggle")("ngIfElse", _r3);
    ɵɵadvance(3);
    ɵɵproperty("ngIf", ctx_r0.hasButtons);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r0.loading);
} }
function TapConfigItemComponent_ion_item_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementStart(0, "ion-item");
    ɵɵelementStart(1, "ion-text", 40);
    ɵɵelement(2, "ion-icon", 12);
    ɵɵtext(3);
    ɵɵelementEnd();
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = ɵɵnextContext();
    ɵɵadvance(3);
    ɵɵtextInterpolate1(" Failed to write value: ", ctx_r1.writeError.message, " ");
} }
class TapConfigItemComponent {
    constructor(formBuilder, tapService, toastController) {
        this.tapService = tapService;
        this.toastController = toastController;
        this.focusOut = new EventEmitter();
        this.onSubmit = new EventEmitter();
        this.refresh = false;
        this.loading = false;
        this.placeholder = '';
        this.editMode = false;
        this.displayedValue = '';
        this.form = formBuilder.group({
            field: [''],
        });
        this.pendingCallManager = PendingCallManager.create(this.tapService);
    }
    set info(config) {
        const defaultConfig = defaultInfoResolverConfig.find((v) => config.key === v.key);
        if (defaultConfig) {
            config = Object.assign(Object.assign({}, defaultConfig), config);
        }
        this.onConfigChange(config);
        this.updateDisplayValue();
        // this.fetchValueIfRequired();
    }
    get info() {
        return this.config;
    }
    get hasButtons() {
        return this.refresh || this.editable || this.pendingEditCall;
    }
    get originalValue() {
        var _a;
        return (_a = this.config.resolvedValue) === null || _a === void 0 ? void 0 : _a.value;
    }
    get field() {
        return getFormFieldOrError(this.form, 'field');
    }
    get config() {
        if (!this._config) {
            throw LibError.componentArgumentRequired('TapConfigItemComponent', 'info');
        }
        return this._config;
    }
    get inputOptions() {
        return this.info.input || {};
    }
    get editable() {
        return this.config.editable;
    }
    get pendingEditCall() {
        return this.pendingCallManager.pendingCall;
    }
    onConfigChange(config) {
        var _a;
        (_a = this.valueSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
        this._config = config;
        this.initializeConfig();
        const params = this.params || config.params;
        if (config.input && config.input.type === 'password') {
            this.setDisplayValue('');
        }
        if (config.params && !this.params) {
            this.params = config.params;
        }
        if (config.formValidators) {
            this.field.setValidators(config.formValidators);
        }
        this.valueSubscription = this.tapService
            .getKeyInfo$(config.key, params)
            .subscribe((newValue) => {
            config.resolvedValue = newValue;
            if (newValue.error) {
                this.setReadError(newValue.error);
            }
            else {
                this.readError = undefined;
                this.setDisplayValue(newValue.value);
                this.setFieldValue(newValue.value);
            }
        });
    }
    initializeConfig() {
        if (this.config.init) {
            this.config.init(this.tapService, this.config).catch((err) => {
                this.setReadError(err);
            });
        }
    }
    setWriteError(error) {
        this.writeError = this.userFriendlyError(error, 'write');
    }
    setReadError(error) {
        this.readError = this.userFriendlyError(error, 'read');
    }
    userFriendlyError(error, action) {
        if (isCodeError(TapError.Code.ExecuteRequestError, error)) {
            error = error.cause || error;
        }
        if (isCodeError(TapResponseStatusError.Code.ResponseStatusError, error)) {
            const tapResponseStatusError = error;
            const statusCode = tapResponseStatusError.response.status;
            let message;
            switch (statusCode) {
                case ResultCode.UNAUTHORIZED:
                    message = `You are not authorized to ${action} this value. Try to login first.`;
                    break;
                case ResultCode.RESOURCE_LOCKED:
                    message = `This value is ${action} protected`;
                    break;
                default:
                    message = tapResponseStatusToString(statusCode);
            }
            error = new Error(message);
        }
        return error;
    }
    ngOnDestroy() {
        var _a;
        // this.tapService.unregisterEventListener(this);
        (_a = this.valueSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
        this.pendingCallManager.destroy();
        // this.pendingTapCall.unregister(this);
    }
    close() { }
    submit($event) {
        debug('submit', $event);
        this.field.updateValueAndValidity();
        if (!this.field.valid) {
            this.writeError = new Error('Invalid value');
            return;
        }
        // this.onSubmit.emit(event);
        const value = this.getFieldValue();
        // debug(`Creating call new value:`, value, `valid: ${this.field.valid}`)
        const params = this.params || this.config.params;
        const call = () => __awaiter(this, void 0, void 0, function* () {
            yield this.tapService.putInfo(this.info.key, value, params);
            return value;
        });
        this.runCall(call);
    }
    runCall(call) {
        this.loading = true;
        this.pendingCallManager
            .exec(call)
            .then((value) => __awaiter(this, void 0, void 0, function* () {
            yield this.showToast('Value saved!', 'success');
            this.config.resolvedValue = {
                loadDate: new Date(),
                value: value,
            };
            this.writeError = undefined;
            this.editMode = false;
            this.updateDisplayValue();
        }))
            .catch((err) => {
            this.setWriteError(err);
            this.field.setErrors({
                write: err.message,
            });
        })
            .finally(() => {
            this.loading = false;
        });
    }
    onValueClick() {
        if (this.editable) {
            this.editMode = true;
        }
    }
    explainPendingCall() {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.showToast('Please reconnect your Tap to save pending changes');
        });
    }
    onFocusOut() {
        this.focusOut.emit(this.field.value);
    }
    isEdited() {
        return this.field.value !== this.originalValue;
    }
    cancelEdit($event) {
        debug(this.config.key, 'cancel edit', $event);
        this.writeError = undefined;
        if (this.pendingCallManager.hasPendingCall()) {
            this.pendingCallManager.cancel();
        }
        else {
            this.editMode = false;
            this.restaureValue();
        }
    }
    getFieldValue() {
        let fieldValue = this.field.value;
        if (this.config.editFormatter) {
            fieldValue = this.config.editFormatter.read(fieldValue);
        }
        return fieldValue;
    }
    // setValue(value: any) {
    //   debug(`Set value`, value);
    //   this.displayedValue = this.resolveValueForView();
    //   if (this._info.editFormatter) {
    //     value = this._info.editFormatter.write(value);
    //   }
    //   // let formValue = this.field.value;
    //   this.field.setValue(
    //     value
    //   );
    // }
    showToast(msg, color) {
        return __awaiter(this, void 0, void 0, function* () {
            const toast = yield this.toastController.create({
                message: msg,
                duration: 2000,
                position: 'bottom',
                color: color,
            });
            yield toast.present();
        });
    }
    refreshValue() {
        return this._execRefreshKey();
    }
    _execRefreshKey() {
        return this.tapService.infoResolver.refreshKey(this.config.key, this.params || this.config.params);
    }
    restaureValue() {
        this.setFieldValue(this.originalValue);
    }
    setFieldValue(value) {
        const formattedValue = this.config.editFormatter
            ? this.config.editFormatter.write(value)
            : value;
        debug(this.config.key, 'setFieldValue with', formattedValue);
        this.field.setValue(formattedValue);
    }
    updateDisplayValue() {
        if (this.config.resolvedValue) {
            if (this.config.resolvedValue.error) {
                this.displayedValue = this.config.resolvedValue.error.message;
            }
            else {
                const value = this.config.resolvedValue.value;
                this.setDisplayValue(value);
                this.setFieldValue(value);
            }
        }
        else {
            debug(this.config.key, 'Value is not loaded yet', this.config.resolvedValue);
        }
        // TODO loading
    }
    setDisplayValue(value) {
        var _a, _b;
        if (value instanceof Error) {
            return value.message;
        }
        else {
            let stringValue;
            if (this.config.viewFormatter) {
                stringValue = this.config.viewFormatter(value);
            }
            else if (typeof value === 'object') {
                stringValue = JSON.stringify(value);
            }
            else if (((_a = this.config.input) === null || _a === void 0 ? void 0 : _a.type) === 'select') {
                stringValue =
                    ((_b = this.getSelectedOption(value)) === null || _b === void 0 ? void 0 : _b.text) ||
                        (value !== undefined ? value.toString() : '');
            }
            else {
                stringValue = value !== undefined ? value.toString() : '';
            }
            // debug(`${this.config.key} setDisplayValue with`, stringValue);
            this.displayedValue = stringValue;
            return stringValue;
        }
    }
    getSelectedOption(value) {
        var _a, _b;
        return (_b = (_a = this.config.input) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.find((option) => option.key === value);
    }
    get selectedOption() {
        var _a;
        return this.getSelectedOption((_a = this.config.resolvedValue) === null || _a === void 0 ? void 0 : _a.value);
    }
    // async fetchValueIfRequired() {
    //   console.log('fetchValueIfRequired');
    //   if (!this.config.resolvedValue) {
    //     await this.fetchValue();
    //   }
    // }
    fetchValue() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.config.getValue) {
                const refreshedValue = yield this.tapService.infoResolver.refreshKey(this.config.key, this.params);
            }
        });
    }
}
/** @nocollapse */ TapConfigItemComponent.ɵfac = function TapConfigItemComponent_Factory(t) { return new (t || TapConfigItemComponent)(ɵɵdirectiveInject(FormBuilder), ɵɵdirectiveInject(CurrentDeviceService), ɵɵdirectiveInject(ToastController)); };
/** @nocollapse */ TapConfigItemComponent.ɵcmp = ɵɵdefineComponent({ type: TapConfigItemComponent, selectors: [["tap-config-item"]], inputs: { params: "params", info: "info", refresh: "refresh", editMode: "editMode" }, outputs: { focusOut: "focusOut", onSubmit: "onSubmit" }, decls: 2, vars: 2, consts: [[3, "formGroup", "lines", 4, "ngIf"], [4, "ngIf"], [3, "formGroup", "lines"], ["formControlName", "field", 3, "disabled", 4, "ngIf", "ngIfElse"], ["viewEditSeparated", ""], ["slot", "end", 4, "ngIf"], ["formControlName", "field", 3, "disabled"], [4, "ngIf", "ngIfElse"], ["editModeTemplate", ""], ["color", "warning", "class", "read-value-error", 3, "class", "click", 4, "ngIf", "ngIfElse"], ["noReadErrorTemplate", ""], ["color", "warning", 1, "read-value-error", 3, "click"], ["name", "alert-circle"], [3, "ngSwitch"], [3, "class", "click", 4, "ngSwitchCase"], ["class", "tap-config-item-value", 3, "class", "click", 4, "ngSwitchDefault"], [3, "click"], [3, "name", 4, "ngIf"], [1, "tap-config-item-value"], [3, "name"], [1, "tap-config-item-value", 3, "click"], ["formControlName", "field", 3, "multiple", 4, "ngSwitchCase"], ["appAutofocus", "", "class", "cellInput", "formControlName", "field", 3, "disabled", "maxlength", "minlength", "max", "min", "pattern", "placeholder", "type", "keydown.enter", "keydown.escape", 4, "ngSwitchDefault"], ["formControlName", "field", 3, "multiple"], [3, "value", 4, "ngFor", "ngForOf"], [3, "value"], ["appAutofocus", "", "formControlName", "field", 1, "cellInput", 3, "disabled", "maxlength", "minlength", "max", "min", "pattern", "placeholder", "type", "keydown.enter", "keydown.escape"], ["slot", "end"], ["color", "warning", 3, "disabled", "click", 4, "ngIf"], [4, "ngIf", "ngIfThen", "ngIfElse"], ["EditableButtons", ""], ["NotEditableButtons", ""], [3, "disabled", "click", 4, "ngIf"], ["color", "warning", 3, "disabled", "click"], [3, "click", 4, "ngIf"], ["name", "create"], [3, "disabled", "click"], ["name", "send"], ["name", "close"], ["name", "sync"], ["color", "danger", 1, "tap-config-item-error"]], template: function TapConfigItemComponent_Template(rf, ctx) { if (rf & 1) {
        ɵɵtemplate(0, TapConfigItemComponent_ion_item_0_Template, 6, 6, "ion-item", 0);
        ɵɵtemplate(1, TapConfigItemComponent_ion_item_1_Template, 4, 1, "ion-item", 1);
    } if (rf & 2) {
        ɵɵproperty("ngIf", ctx._config);
        ɵɵadvance(1);
        ɵɵproperty("ngIf", ctx.writeError);
    } }, directives: [NgIf, IonItem, NgControlStatusGroup, FormGroupDirective, IonToggle, BooleanValueAccessor, NgControlStatus, FormControlName, IonText, IonIcon, NgSwitch, NgSwitchCase, NgSwitchDefault, IonSelect, SelectValueAccessor, NgForOf, IonSelectOption, IonInput, TextValueAccessor, AutoFocusDirective, MaxLengthValidator, MinLengthValidator, PatternValidator, IonButtons, IonButton, IonSpinner], styles: [".cell[_ngcontent-%COMP%]{border:2px solid transparent;padding:11px 0;width:100%;height:100%}.cell[_ngcontent-%COMP%]:hover{cursor:pointer;border:2px dashed #c8c8c8}ion-item[_ngcontent-%COMP%]{--padding-start:0px}.cellInput[_ngcontent-%COMP%]{border:2px solid transparent;padding:11px 20px;width:100%;height:100%}ion-select[_ngcontent-%COMP%]{min-width:150px}.read-value-error[_ngcontent-%COMP%]{font-weight:700}ion-buttons[_ngcontent-%COMP%]{-webkit-margin-start:5px;margin-inline-start:5px}"] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵsetClassMetadata(TapConfigItemComponent, [{
        type: Component,
        args: [{
                selector: 'tap-config-item',
                templateUrl: './tap-config-item.component.html',
                styleUrls: ['./tap-config-item.component.scss'],
            }]
    }], function () { return [{ type: FormBuilder }, { type: CurrentDeviceService }, { type: ToastController }]; }, { focusOut: [{
            type: Output
        }], onSubmit: [{
            type: Output
        }], params: [{
            type: Input
        }], info: [{
            type: Input
        }], refresh: [{
            type: Input
        }], editMode: [{
            type: Input
        }] }); })();

function TapConfigListComponent_ion_grid_0_ion_row_1_ion_icon_5_Template(rf, ctx) { if (rf & 1) {
    ɵɵelement(0, "ion-icon", 7);
} if (rf & 2) {
    const item_r3 = ɵɵnextContext().$implicit;
    ɵɵproperty("name", item_r3.icon);
} }
function TapConfigListComponent_ion_grid_0_ion_row_1_br_6_Template(rf, ctx) { if (rf & 1) {
    ɵɵelement(0, "br");
} }
function TapConfigListComponent_ion_grid_0_ion_row_1_tap_config_item_10_Template(rf, ctx) { if (rf & 1) {
    ɵɵelement(0, "tap-config-item", 8);
} if (rf & 2) {
    const item_r3 = ɵɵnextContext().$implicit;
    const ctx_r6 = ɵɵnextContext(2);
    ɵɵproperty("info", item_r3)("refresh", ctx_r6.itemRefresh)("params", ctx_r6.params);
} }
function TapConfigListComponent_ion_grid_0_ion_row_1_ion_buttons_11_ion_button_1_ion_icon_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelement(0, "ion-icon", 7);
} if (rf & 2) {
    const action_r11 = ɵɵnextContext().$implicit;
    ɵɵproperty("name", action_r11.icon);
} }
function TapConfigListComponent_ion_grid_0_ion_row_1_ion_buttons_11_ion_button_1_Template(rf, ctx) { if (rf & 1) {
    const _r16 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-button", 10);
    ɵɵlistener("click", function TapConfigListComponent_ion_grid_0_ion_row_1_ion_buttons_11_ion_button_1_Template_ion_button_click_0_listener() { ɵɵrestoreView(_r16); const action_r11 = ctx.$implicit; const item_r3 = ɵɵnextContext(2).$implicit; const ctx_r14 = ɵɵnextContext(2); return ctx_r14.clickAction(item_r3, action_r11); });
    ɵɵtemplate(1, TapConfigListComponent_ion_grid_0_ion_row_1_ion_buttons_11_ion_button_1_ion_icon_1_Template, 1, 1, "ion-icon", 4);
    ɵɵtext(2);
    ɵɵelementEnd();
} if (rf & 2) {
    const action_r11 = ctx.$implicit;
    const ctx_r10 = ɵɵnextContext(4);
    ɵɵproperty("color", action_r11.color)("disabled", ctx_r10.loading);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", action_r11.icon);
    ɵɵadvance(1);
    ɵɵtextInterpolate1(" ", action_r11.title, " ");
} }
function TapConfigListComponent_ion_grid_0_ion_row_1_ion_buttons_11_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementStart(0, "ion-buttons");
    ɵɵtemplate(1, TapConfigListComponent_ion_grid_0_ion_row_1_ion_buttons_11_ion_button_1_Template, 3, 4, "ion-button", 9);
    ɵɵelementEnd();
} if (rf & 2) {
    const item_r3 = ɵɵnextContext().$implicit;
    ɵɵadvance(1);
    ɵɵproperty("ngForOf", item_r3.actions);
} }
function TapConfigListComponent_ion_grid_0_ion_row_1_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementStart(0, "ion-row");
    ɵɵelementStart(1, "ion-col", 2);
    ɵɵelementStart(2, "ion-label");
    ɵɵelementStart(3, "span", 3);
    ɵɵtext(4);
    ɵɵelementEnd();
    ɵɵtemplate(5, TapConfigListComponent_ion_grid_0_ion_row_1_ion_icon_5_Template, 1, 1, "ion-icon", 4);
    ɵɵtemplate(6, TapConfigListComponent_ion_grid_0_ion_row_1_br_6_Template, 1, 0, "br", 0);
    ɵɵelementStart(7, "span", 5);
    ɵɵtext(8);
    ɵɵelementEnd();
    ɵɵelementEnd();
    ɵɵelementEnd();
    ɵɵelementStart(9, "ion-col", 2);
    ɵɵtemplate(10, TapConfigListComponent_ion_grid_0_ion_row_1_tap_config_item_10_Template, 1, 3, "tap-config-item", 6);
    ɵɵtemplate(11, TapConfigListComponent_ion_grid_0_ion_row_1_ion_buttons_11_Template, 2, 1, "ion-buttons", 0);
    ɵɵelementEnd();
    ɵɵelementEnd();
} if (rf & 2) {
    const item_r3 = ctx.$implicit;
    ɵɵclassMapInterpolate1("tap-config-row-", item_r3.key, "");
    ɵɵadvance(4);
    ɵɵtextInterpolate(item_r3.title);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", item_r3.icon);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", item_r3.description);
    ɵɵadvance(2);
    ɵɵtextInterpolate(item_r3.description);
    ɵɵadvance(2);
    ɵɵproperty("ngIf", !item_r3.actions);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", item_r3.actions);
} }
function TapConfigListComponent_ion_grid_0_ion_toolbar_2_Template(rf, ctx) { if (rf & 1) {
    const _r19 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "ion-toolbar");
    ɵɵelementStart(1, "ion-button", 11);
    ɵɵlistener("click", function TapConfigListComponent_ion_grid_0_ion_toolbar_2_Template_ion_button_click_1_listener() { ɵɵrestoreView(_r19); const ctx_r18 = ɵɵnextContext(2); return ctx_r18.refresh(); });
    ɵɵelement(2, "ion-icon", 12);
    ɵɵelementEnd();
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r2 = ɵɵnextContext(2);
    ɵɵadvance(1);
    ɵɵproperty("disabled", ctx_r2.loading);
} }
function TapConfigListComponent_ion_grid_0_Template(rf, ctx) { if (rf & 1) {
    ɵɵelementStart(0, "ion-grid");
    ɵɵtemplate(1, TapConfigListComponent_ion_grid_0_ion_row_1_Template, 12, 9, "ion-row", 1);
    ɵɵtemplate(2, TapConfigListComponent_ion_grid_0_ion_toolbar_2_Template, 3, 1, "ion-toolbar", 0);
    ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r0 = ɵɵnextContext();
    ɵɵadvance(1);
    ɵɵproperty("ngForOf", ctx_r0._items);
    ɵɵadvance(1);
    ɵɵproperty("ngIf", ctx_r0.globalRefresh);
} }
class TapConfigListComponent {
    constructor(tapService, toastController) {
        this.tapService = tapService;
        this.toastController = toastController;
        // dataSource: DeviceInfoDataSource;
        this.header = undefined;
        this.globalRefresh = true;
        this.itemRefresh = false;
        this.lines = 'full';
        this.columns = [
            'key',
            'value',
        ];
        this.loading = false;
        this._items = [];
    }
    set items(items) {
        if (!items) {
            items = [];
        }
        items = items.map((item) => {
            const defaultOption = defaultInfoResolverConfig.find((d) => item.key === d.key);
            if (defaultOption) {
                item = Object.assign(Object.assign({}, defaultOption), item);
            }
            return item;
        });
        this._items = items;
    }
    ngOnInit() {
        this.sub = this.tapService.connectionState.subscribe((event) => {
            switch (event.newState) {
                case ConnectionState.CONNECTED:
                    for (const item of this._items) {
                        if (item.resolvedValue &&
                            item.resolvedValue.error &&
                            item.resolvedValue.error) {
                            // console.log(`Item ${item.key} has an error:`, item.resolvedValue.error);
                        }
                    }
                    //
                    break;
            }
        });
    }
    ngOnDestroy() {
        this._items = [];
        if (this.sub) {
            this.sub.unsubscribe();
        }
    }
    refresh() {
        this.loading = true;
        this.tapService.infoResolver
            .refreshKeys(this._items.map((value) => value === null || value === void 0 ? void 0 : value.key))
            .finally(() => (this.loading = false));
    }
    onSubmitValue() { }
    clickAction(item, action) {
        this.loading = true;
        action
            .call(this.tapService.tap)
            .then((response) => {
            response.successful();
            if (action.triggersRefresh) {
                return this.tapService.infoResolver.refreshKeys(action.triggersRefresh);
            }
        })
            .catch((err) => __awaiter(this, void 0, void 0, function* () {
            yield this.onError(err);
        }))
            .then(() => {
            this.loading = false;
        });
    }
    onError(err) {
        return __awaiter(this, void 0, void 0, function* () {
            console.warn(err);
            const toast = yield this.toastController.create({
                message: err.message || 'Unknown error',
                duration: 3000,
                position: 'bottom',
            });
            yield toast.present();
        });
    }
    loadIfNeeded() {
        return __awaiter(this, void 0, void 0, function* () {
            console.log('TapConfigListComponent', 'load');
            yield this.tapService.infoResolver.loadKeysIfNotInCache(this._items.map((value) => value === null || value === void 0 ? void 0 : value.key));
        });
    }
    isLoaded(item) {
        return this.tapService.infoResolver.isLoaded(item.key, this.params);
    }
}
/** @nocollapse */ TapConfigListComponent.ɵfac = function TapConfigListComponent_Factory(t) { return new (t || TapConfigListComponent)(ɵɵdirectiveInject(CurrentDeviceService), ɵɵdirectiveInject(ToastController)); };
/** @nocollapse */ TapConfigListComponent.ɵcmp = ɵɵdefineComponent({ type: TapConfigListComponent, selectors: [["tap-config-list"]], inputs: { header: "header", globalRefresh: "globalRefresh", itemRefresh: "itemRefresh", lines: "lines", columns: "columns", params: "params", items: "items" }, decls: 1, vars: 1, consts: [[4, "ngIf"], [3, "class", 4, "ngFor", "ngForOf"], ["size-xs", "12", "size-sm", "6"], [1, "item-title"], [3, "name", 4, "ngIf"], [1, "item-description"], [3, "info", "refresh", "params", 4, "ngIf"], [3, "name"], [3, "info", "refresh", "params"], [3, "color", "disabled", "click", 4, "ngFor", "ngForOf"], [3, "color", "disabled", "click"], ["float-right", "", "size", "small", 3, "disabled", "click"], ["name", "refresh"]], template: function TapConfigListComponent_Template(rf, ctx) { if (rf & 1) {
        ɵɵtemplate(0, TapConfigListComponent_ion_grid_0_Template, 3, 2, "ion-grid", 0);
    } if (rf & 2) {
        ɵɵproperty("ngIf", ctx._items && ctx._items.length > 0);
    } }, directives: [NgIf, IonGrid, NgForOf, IonRow, IonCol, IonLabel, IonIcon, TapConfigItemComponent, IonButtons, IonButton, IonToolbar], styles: ["table[_ngcontent-%COMP%]{width:100%}.item-title[_ngcontent-%COMP%]{color:#333;font-weight:700;font-size:1.05em}"] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵsetClassMetadata(TapConfigListComponent, [{
        type: Component,
        args: [{
                selector: 'tap-config-list',
                templateUrl: './tap-config-list.component.html',
                styleUrls: ['./tap-config-list.component.scss'],
            }]
    }], function () { return [{ type: CurrentDeviceService }, { type: ToastController }]; }, { header: [{
            type: Input
        }], globalRefresh: [{
            type: Input
        }], itemRefresh: [{
            type: Input
        }], lines: [{
            type: Input
        }], columns: [{
            type: Input
        }], params: [{
            type: Input
        }], items: [{
            type: Input
        }] }); })();

class TapConfigModule {
}
/** @nocollapse */ TapConfigModule.ɵfac = function TapConfigModule_Factory(t) { return new (t || TapConfigModule)(); };
/** @nocollapse */ TapConfigModule.ɵmod = ɵɵdefineNgModule({ type: TapConfigModule });
/** @nocollapse */ TapConfigModule.ɵinj = ɵɵdefineInjector({ imports: [[LibCommonModule, FormsModule, ReactiveFormsModule]] });
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && ɵɵsetNgModuleScope(TapConfigModule, { declarations: [TapConfigItemComponent, TapConfigListComponent], imports: [LibCommonModule, FormsModule, ReactiveFormsModule], exports: [TapConfigItemComponent, TapConfigListComponent] }); })();
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵsetClassMetadata(TapConfigModule, [{
        type: NgModule,
        args: [{
                declarations: [TapConfigItemComponent, TapConfigListComponent],
                exports: [TapConfigItemComponent, TapConfigListComponent],
                imports: [LibCommonModule, FormsModule, ReactiveFormsModule],
            }]
    }], null, null); })();

function parseTapConfiguratorConfig(fileContent) {
    if (isJsonString(fileContent)) {
        const config = JSON.parse(fileContent);
        // this.tapConfigPickerservice.onConfigSelected(config);
        return config;
    }
    else {
        // if (IotizeConfigFactory.fromXML(fileContent)) {
        return fromXml(fileContent);
    }
}
function isJsonString(str) {
    try {
        const json = JSON.parse(str);
        return typeof json === 'object';
    }
    catch (e) {
        return false;
    }
}
function fromXml(fileContent) {
    console.log('File content', fileContent);
    const parser = new DOMParser();
    const xmlConfig = parser.parseFromString(fileContent, 'application/xml');
    // let xmlConfig = parse(fileContent);
    const config = new IoTizeStudioToTapConfigConverter().convert(new DomElementAccessor(xmlConfig));
    return { config };
}

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

export { TapConfigItemComponent, TapConfigListComponent, TapConfigModule, defaultInfoResolverConfig, fromXml, isJsonString, isTapConfigured, parseTapConfiguratorConfig };
//# sourceMappingURL=iotize-ionic-config.js.map
