import { __spread, __extends, __awaiter, __generator, __assign } from 'tslib';
import { Injectable, ɵɵdefineInjectable, ɵɵinject, EventEmitter, Component, Input, Output, NgModule } from '@angular/core';
import { Validators, FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TargetS3PProtocolConfiguration, SerialSettings } from '@iotize/tap/service/impl/target';
import { deepEqual } from '@iotize/common/utility';
import { BehaviorSubject, Subject } from 'rxjs';
import { CurrentDeviceService, LibCommonModule } from '@iotize/ionic';
import { CommonModule } from '@angular/common';

/**
 * @fileoverview added by tsickle
 * Generated from: lib/definitions.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/** @type {?} */
var SERIAL_SETTINGS_FIELDS = [
    'baudRate',
    'dataBits',
    'bitParity',
    'stopBits',
    'hardwareFlowControl',
    'handshakeDelimiter',
    'timeout'
];
/** @type {?} */
var MODBUS_SETTINGS_FIELDS = __spread(SERIAL_SETTINGS_FIELDS, [
    'offsetFirstRegister',
    'slave'
]);
/** @type {?} */
var TAPNPASS_SETTINGS_FIELDS = [
    'physicalPort'
];
/** @type {?} */
var ALL_SETTINGS_FIELDS = __spread(SERIAL_SETTINGS_FIELDS, MODBUS_SETTINGS_FIELDS);
var ProtocolConfigurationError = /** @class */ (function (_super) {
    __extends(ProtocolConfigurationError, _super);
    function ProtocolConfigurationError(msg, cause) {
        var _this = _super.call(this, msg) || this;
        _this.cause = cause;
        _this.code = 'ProtocolConfigurationError';
        return _this;
    }
    /**
     * @param {?} err
     * @param {?} msg
     * @return {?}
     */
    ProtocolConfigurationError.tapResponseError = /**
     * @param {?} err
     * @param {?} msg
     * @return {?}
     */
    function (err, msg) {
        /** @type {?} */
        var fullMsg = msg + " - " + err.message;
        return new ProtocolConfigurationError(fullMsg, err);
    };
    return ProtocolConfigurationError;
}(Error));
if (false) {
    /** @type {?} */
    ProtocolConfigurationError.prototype.code;
    /** @type {?} */
    ProtocolConfigurationError.prototype.cause;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/protocol-configuration.service.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/** @type {?} */
var TAG = 'SerialSettings';
var ProtocolConfigurationService = /** @class */ (function () {
    function ProtocolConfigurationService(tapService) {
        this.tapService = tapService;
        this._s3pProtocolConfiguration = {
            mode: TargetS3PProtocolConfiguration.Mode.INDEXED,
            delay: 1
        };
        this._defaultSettings = {
            serial: {
                physicalPort: SerialSettings.PhysicalPort.AUTO,
                stopBits: SerialSettings.StopBits.ONE,
                bitParity: SerialSettings.BitParity.NONE,
                dataBits: SerialSettings.DataBits._8,
                hardwareFlowControl: SerialSettings.HardwareFlowControl.NONE,
                handshakeDelimiter: SerialSettings.HandshakeDelimiter.NONE,
                timeout: 50,
                baudRate: 187500,
            },
            modbus: {
                offsetFirstRegister: false,
                slave: 0
            }
        };
        this.pendingSettings$ = new BehaviorSubject(this._defaultSettings); // displayed settings
        // displayed settings
        this.loading = new BehaviorSubject(false);
        // real settings
        this.errors = new Subject();
        this._tapSettings = undefined;
    }
    Object.defineProperty(ProtocolConfigurationService.prototype, "pendingSettings", {
        get: /**
         * @return {?}
         */
        function () {
            return this.pendingSettings$.value;
        },
        set: /**
         * @param {?} settings
         * @return {?}
         */
        function (settings) {
            this.pendingSettings$.next(settings);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ProtocolConfigurationService.prototype, "tap", {
        get: /**
         * @return {?}
         */
        function () {
            return this.tapService.tap;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @return {?}
     */
    ProtocolConfigurationService.prototype.refresh = /**
     * @return {?}
     */
    function () {
        return __awaiter(this, void 0, void 0, function () {
            var tapSettings, err_1, error;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this.loading.next(true);
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 3, , 4]);
                        return [4 /*yield*/, this.tap.service.target.getSerialModbusConfiguration()];
                    case 2:
                        tapSettings = (_a.sent()).body();
                        this._tapSettings = tapSettings;
                        this.pendingSettings$.next(tapSettings);
                        // debug(TAG, 'Refreshed settings: ', this.pendingSettings);
                        this.loading.next(false);
                        return [3 /*break*/, 4];
                    case 3:
                        err_1 = _a.sent();
                        error = ProtocolConfigurationError.tapResponseError(err_1, 'Failed reading serial settings from Tap');
                        this.loading.next(false);
                        this.onError(error);
                        throw error;
                    case 4: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * @param {?=} temporary
     * @param {?=} reconnectTarget
     * @return {?}
     */
    ProtocolConfigurationService.prototype.applyChanges = /**
     * @param {?=} temporary
     * @param {?=} reconnectTarget
     * @return {?}
     */
    function (temporary, reconnectTarget) {
        if (temporary === void 0) { temporary = true; }
        if (reconnectTarget === void 0) { reconnectTarget = true; }
        return __awaiter(this, void 0, void 0, function () {
            var error_1;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this.loading.next(true);
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 5, , 6]);
                        return [4 /*yield*/, this.setSerialModbusConfiguration(temporary)];
                    case 2:
                        _a.sent();
                        if (!reconnectTarget) return [3 /*break*/, 4];
                        return [4 /*yield*/, this.reconnectTarget()];
                    case 3:
                        _a.sent();
                        _a.label = 4;
                    case 4:
                        this._tapSettings = __assign({}, this.pendingSettings);
                        this.loading.next(false);
                        return [3 /*break*/, 6];
                    case 5:
                        error_1 = _a.sent();
                        this.loading.next(false);
                        this.onError(error_1);
                        throw error_1;
                    case 6: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * @return {?}
     */
    ProtocolConfigurationService.prototype.discardChanges = /**
     * @return {?}
     */
    function () {
        /** @type {?} */
        var prevSettings = (this._tapSettings ? this._tapSettings : this._defaultSettings);
        this.pendingSettings$.next(prevSettings);
    };
    /**
     * @return {?}
     */
    ProtocolConfigurationService.prototype.hasChanges = /**
     * @return {?}
     */
    function () {
        if (!this._tapSettings) {
            return true;
        }
        return !deepEqual(this.pendingSettings, this._tapSettings);
    };
    /**
     * @private
     * @param {?=} temporary
     * @return {?}
     */
    ProtocolConfigurationService.prototype.setSerialModbusConfiguration = /**
     * @private
     * @param {?=} temporary
     * @return {?}
     */
    function (temporary) {
        if (temporary === void 0) { temporary = true; }
        return __awaiter(this, void 0, void 0, function () {
            var err_2;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        _a.trys.push([0, 5, , 6]);
                        if (!temporary) return [3 /*break*/, 2];
                        return [4 /*yield*/, this.tap.service.target.setSerialModbusConfiguration(this.pendingSettings)];
                    case 1:
                        (_a.sent()).successful();
                        return [3 /*break*/, 4];
                    case 2: return [4 /*yield*/, this.tap.service.target.putSerialModbusConfiguration(this.pendingSettings)];
                    case 3:
                        (_a.sent()).successful();
                        _a.label = 4;
                    case 4: return [3 /*break*/, 6];
                    case 5:
                        err_2 = _a.sent();
                        throw ProtocolConfigurationError.tapResponseError(err_2, "Failed writing serial settings to Tap");
                    case 6: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * @return {?}
     */
    ProtocolConfigurationService.prototype.reconnectTarget = /**
     * @return {?}
     */
    function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.tap.service.target.disconnect()];
                    case 1:
                        _a.sent();
                        return [4 /*yield*/, this.tap.service.target.connect()];
                    case 2:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * @param {?} error
     * @return {?}
     */
    ProtocolConfigurationService.prototype.onError = /**
     * @param {?} error
     * @return {?}
     */
    function (error) {
        this.errors.next(error);
    };
    ProtocolConfigurationService.decorators = [
        { type: Injectable, args: [{
                    providedIn: 'root'
                },] }
    ];
    /** @nocollapse */
    ProtocolConfigurationService.ctorParameters = function () { return [
        { type: CurrentDeviceService }
    ]; };
    /** @nocollapse */ ProtocolConfigurationService.ɵprov = ɵɵdefineInjectable({ factory: function ProtocolConfigurationService_Factory() { return new ProtocolConfigurationService(ɵɵinject(CurrentDeviceService)); }, token: ProtocolConfigurationService, providedIn: "root" });
    return ProtocolConfigurationService;
}());
if (false) {
    /**
     * @type {?}
     * @protected
     */
    ProtocolConfigurationService.prototype._s3pProtocolConfiguration;
    /**
     * @type {?}
     * @protected
     */
    ProtocolConfigurationService.prototype._defaultSettings;
    /** @type {?} */
    ProtocolConfigurationService.prototype.pendingSettings$;
    /** @type {?} */
    ProtocolConfigurationService.prototype.loading;
    /**
     * @type {?}
     * @private
     */
    ProtocolConfigurationService.prototype._tapSettings;
    /** @type {?} */
    ProtocolConfigurationService.prototype.errors;
    /** @type {?} */
    ProtocolConfigurationService.prototype.tapService;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/tap-protocol-configuration-form/tap-protocol-configuration-form.component.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/** @type {?} */
var TAG$1 = 'TapProtocolConfiguration';
var TapProtocolConfigurationFormComponent = /** @class */ (function () {
    function TapProtocolConfigurationFormComponent(formBuilder, protocolConfigurationService) {
        this.protocolConfigurationService = protocolConfigurationService;
        this.customBaudRate = false;
        this.baudRates = [
            300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200,
            187500, 230400, 460800, 921600
        ];
        this.fields = ALL_SETTINGS_FIELDS;
        this.valueChanges = new EventEmitter();
        // TODO add validators
        /** @type {?} */
        var formConfig = {
            baudRate: ['', [Validators.required]],
            bitParity: [''],
            dataBits: [''],
            hardwareFlowControl: [''],
            handshakeDelimiter: [
                SerialSettings.HandshakeDelimiter.NONE
            ],
            physicalPort: [''],
            stopBits: [''],
            offsetFirstRegister: [''],
            // identification: [''],
            // ledStatus: [''],
            slave: [''],
            timeout: [''],
        };
        this.form = formBuilder.group(formConfig);
    }
    Object.defineProperty(TapProtocolConfigurationFormComponent.prototype, "values", {
        set: /**
         * @param {?} v
         * @return {?}
         */
        function (v) {
            if (v) {
                this.updateFormValue(v);
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @param {?} field
     * @return {?}
     */
    TapProtocolConfigurationFormComponent.prototype.hasField = /**
     * @param {?} field
     * @return {?}
     */
    function (field) {
        return this.fields.indexOf(field) >= 0;
    };
    Object.defineProperty(TapProtocolConfigurationFormComponent.prototype, "SerialSettings", {
        get: /**
         * @return {?}
         */
        function () {
            return SerialSettings;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @param {?} settings
     * @return {?}
     */
    TapProtocolConfigurationFormComponent.prototype.updateFormValue = /**
     * @param {?} settings
     * @return {?}
     */
    function (settings) {
        /** @type {?} */
        var newValues = __assign(__assign({}, settings.modbus), settings.serial);
        for (var key in newValues) {
            /** @type {?} */
            var field = this.form.get(key);
            if (field) {
                field.setValue(newValues[key], {
                    emitEvent: false
                });
            }
        }
    };
    /**
     * @return {?}
     */
    TapProtocolConfigurationFormComponent.prototype.ngOnInit = /**
     * @return {?}
     */
    function () {
        var _this = this;
        // debug(TAG, 'ngOnInit');
        /** @type {?} */
        var settings = this.protocolConfigurationService.pendingSettings;
        this.updateFormValue(settings);
        this.form.valueChanges
            .subscribe((/**
         * @param {?} newValue
         * @return {?}
         */
        function (newValue) {
            // debug(TAG, 'Protocol configuration changed:', newValue);
            /** @type {?} */
            var netProtocolConfig = {
                modbus: {
                    offsetFirstRegister: newValue.offsetFirstRegister,
                    slave: newValue.slave
                },
                serial: {
                    baudRate: newValue.baudRate,
                    bitParity: newValue.bitParity,
                    dataBits: newValue.dataBits,
                    handshakeDelimiter: newValue.handshakeDelimiter,
                    hardwareFlowControl: newValue.hardwareFlowControl,
                    physicalPort: newValue.physicalPort,
                    stopBits: newValue.stopBits,
                    timeout: newValue.timeout
                }
            };
            _this.valueChanges.emit(netProtocolConfig);
            _this.protocolConfigurationService.pendingSettings = netProtocolConfig;
        }));
        this.protocolConfigurationService
            .pendingSettings$
            .subscribe((/**
         * @param {?} newSettings
         * @return {?}
         */
        function (newSettings) {
            // debug(TAG, 'Refreshing form value', newSettings);
            if (_this.baudRates.indexOf(newSettings.serial.baudRate) === -1) {
                _this.customBaudRate = true;
            }
            _this.form.setValue(newSettings, {
                emitEvent: false
            });
        }));
    };
    TapProtocolConfigurationFormComponent.decorators = [
        { type: Component, args: [{
                    selector: 'tap-protocol-configuration-form',
                    template: "<form [formGroup]=\"form\">\r\n    <ion-item *ngIf=\"hasField('baudRate')\">\r\n        <ion-label>\r\n            Baud rate\r\n        </ion-label>\r\n        <!-- <ion-button fill=\"clear\" slot=\"end\" (click)=\"customBaudRate = !customBaudRate\">\r\n                    <ion-icon name=\"swap\"></ion-icon>\r\n                </ion-button> -->\r\n        <ion-input slot=\"end\" *ngIf=\"customBaudRate\" type=\"number\" [formControlName]=\"'baudRate'\"></ion-input>\r\n        <ion-select slot=\"end\" *ngIf=\"!customBaudRate\" [formControlName]=\"'baudRate'\">\r\n            <ion-select-option *ngFor=\"let baud of baudRates\" [value]=\"baud\">\r\n                {{baud}}\r\n                bauds\r\n            </ion-select-option>\r\n        </ion-select>\r\n    </ion-item>\r\n    <ion-item *ngIf=\"hasField('dataBits')\">\r\n        <ion-label>Data bits</ion-label>\r\n        <ion-select [formControlName]=\"'dataBits'\">\r\n            <ion-select-option *ngFor=\"let option of SerialSettings.DataBits | enum\" [value]=\"option.key\">\r\n                {{option.value | trim:'_'}}\r\n            </ion-select-option>\r\n        </ion-select>\r\n    </ion-item>\r\n    <ion-item *ngIf=\"hasField('stopBits')\">\r\n        <ion-label>Stop bit</ion-label>\r\n        <ion-select [formControlName]=\"'stopBits'\">\r\n            <ion-select-option *ngFor=\"let option of SerialSettings.StopBits | enum\" [value]=\"option.key\">{{option.value}}\r\n            </ion-select-option>\r\n        </ion-select>\r\n    </ion-item>\r\n    <ion-item *ngIf=\"hasField('bitParity')\">\r\n        <ion-label>Parity</ion-label>\r\n        <ion-select [formControlName]=\"'bitParity'\">\r\n            <ion-select-option *ngFor=\"let option of SerialSettings.BitParity | enum\" [value]=\"option.key\">\r\n                {{option.value}}\r\n            </ion-select-option>\r\n        </ion-select>\r\n    </ion-item>\r\n\r\n    <ion-item *ngIf=\"hasField('hardwareFlowControl')\">\r\n        <ion-label>Hardware flow control</ion-label>\r\n        <ion-select [formControlName]=\"'hardwareFlowControl'\">\r\n            <ion-select-option *ngFor=\"let option of SerialSettings.HardwareFlowControl | enum\" [value]=\"option.key\">\r\n                {{option.value}}\r\n            </ion-select-option>\r\n        </ion-select>\r\n    </ion-item>\r\n<!-- \r\n    <ion-item *ngIf=\"hasField('handshakeDelimiter')\">\r\n        <ion-label>Handshake delimiter</ion-label>\r\n        <ion-select [formControlName]=\"'handshakeDelimiter'\">\r\n            <ion-select-option *ngFor=\"let option of SerialSettings.HandshakeDelimiter | enum\" [value]=\"option.key\">\r\n                {{option.value}}</ion-select-option>\r\n        </ion-select>\r\n    </ion-item> -->\r\n\r\n    <!-- TAPNPASS -->\r\n    <ion-item *ngIf=\"hasField('slave')\">\r\n        <ion-label>Slave number</ion-label>\r\n        <ion-input slot=\"end\" type=\"number\" [formControlName]=\"'slave'\" ></ion-input>\r\n    </ion-item>\r\n\r\n    <ion-item *ngIf=\"hasField('physicalPort')\">\r\n        <ion-label>Physical port</ion-label>\r\n        <ion-select [formControlName]=\"'physicalPort'\">\r\n            <ion-select-option *ngFor=\"let option of SerialSettings.PhysicalPort | enum\" [value]=\"option.key\">\r\n                {{option.value}}</ion-select-option>\r\n        </ion-select>\r\n    </ion-item>\r\n\r\n    <ion-item *ngIf=\"hasField('timeout')\">\r\n        <ion-label>Timeout</ion-label>\r\n        <ion-input slot=\"end\" type=\"number\" [formControlName]=\"'timeout'\"></ion-input>\r\n    </ion-item>\r\n\r\n    <ion-item *ngIf=\"hasField('offsetFirstRegister')\">\r\n        <ion-label>Offset first register</ion-label>\r\n        <ion-select [formControlName]=\"'offsetFirstRegister'\">\r\n            <ion-select-option [value]=\"false\">No</ion-select-option>\r\n            <ion-select-option [value]=\"true\">Yes</ion-select-option>\r\n        </ion-select>\r\n    </ion-item>\r\n</form>\r\n",
                    styles: ["ion-input{text-align:right}"]
                }] }
    ];
    /** @nocollapse */
    TapProtocolConfigurationFormComponent.ctorParameters = function () { return [
        { type: FormBuilder },
        { type: ProtocolConfigurationService }
    ]; };
    TapProtocolConfigurationFormComponent.propDecorators = {
        customBaudRate: [{ type: Input }],
        baudRates: [{ type: Input }],
        fields: [{ type: Input }],
        values: [{ type: Input }],
        valueChanges: [{ type: Output }]
    };
    return TapProtocolConfigurationFormComponent;
}());
if (false) {
    /** @type {?} */
    TapProtocolConfigurationFormComponent.prototype.customBaudRate;
    /** @type {?} */
    TapProtocolConfigurationFormComponent.prototype.baudRates;
    /** @type {?} */
    TapProtocolConfigurationFormComponent.prototype.fields;
    /** @type {?} */
    TapProtocolConfigurationFormComponent.prototype.valueChanges;
    /** @type {?} */
    TapProtocolConfigurationFormComponent.prototype.form;
    /** @type {?} */
    TapProtocolConfigurationFormComponent.prototype.protocolConfigurationService;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/tap-protocol-configuration.module.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
var TapProtocolConfigurationModule = /** @class */ (function () {
    function TapProtocolConfigurationModule() {
    }
    TapProtocolConfigurationModule.decorators = [
        { type: NgModule, args: [{
                    declarations: [
                        TapProtocolConfigurationFormComponent
                    ],
                    exports: [
                        TapProtocolConfigurationFormComponent
                    ],
                    imports: [
                        CommonModule,
                        LibCommonModule,
                        FormsModule,
                        ReactiveFormsModule
                    ],
                    providers: [
                        ProtocolConfigurationService
                    ]
                },] }
    ];
    return TapProtocolConfigurationModule;
}());

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

/**
 * @fileoverview added by tsickle
 * Generated from: iotize-ionic-target-common.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

export { ALL_SETTINGS_FIELDS, MODBUS_SETTINGS_FIELDS, ProtocolConfigurationError, ProtocolConfigurationService, SERIAL_SETTINGS_FIELDS, TAPNPASS_SETTINGS_FIELDS, TapProtocolConfigurationFormComponent, TapProtocolConfigurationModule };
//# sourceMappingURL=iotize-ionic-target-common.js.map
