(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@iotize/device-client.js'), require('@iotize/device-client.js/client/impl'), require('rxjs'), require('rxjs/operators'), require('@iotize/common')) :
    typeof define === 'function' && define.amd ? define('@iotize/device-client.js/datalog', ['@iotize/device-client.js', '@iotize/device-client.js/client/impl', 'rxjs', 'rxjs/operators', '@iotize/common'], factory) :
    (global = global || self, (global.iotize = global.iotize || {}, global.iotize['device-client'] = global.iotize['device-client'] || {}, global.iotize['device-client'].js = global.iotize['device-client'].js || {}, global.iotize['device-client'].js.datalog = factory(global.iotize['device-client'].js, global.iotize['device-client'].js.client.impl, global.rxjs, global.rxjs.operators, global.common)));
}(this, (function (deviceClient, impl, rxjs, operators, common) { 'use strict';

    deviceClient = deviceClient && deviceClient.hasOwnProperty('default') ? deviceClient['default'] : deviceClient;
    impl = impl && impl.hasOwnProperty('default') ? impl['default'] : impl;
    rxjs = rxjs && rxjs.hasOwnProperty('default') ? rxjs['default'] : rxjs;
    operators = operators && operators.hasOwnProperty('default') ? operators['default'] : operators;
    common = common && common.hasOwnProperty('default') ? common['default'] : common;

    var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

    function commonjsRequire () {
    	throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
    }

    function unwrapExports (x) {
    	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
    }

    function createCommonjsModule(fn, module) {
    	return module = { exports: {} }, fn(module, module.exports), module.exports;
    }

    function getCjsExportFromNamespace (n) {
    	return n && n['default'] || n;
    }

    var debug = createCommonjsModule(function (module, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });

    var prefix = '@iotize:device-client.js:datalog';
    exports.debug = common.createDebugger(prefix);

    });

    var debug$1 = unwrapExports(debug);
    var debug_1 = debug.debug;

    var dataLogger = createCommonjsModule(function (module, exports) {
    "use strict";
    var __extends = (commonjsGlobal && commonjsGlobal.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        };
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) {
        var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f) throw new TypeError("Generator is already executing.");
            while (_) try {
                if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
                if (y = 0, t) op = [op[0] & 2, t.value];
                switch (op[0]) {
                    case 0: case 1: t = op; break;
                    case 4: _.label++; return { value: op[1], done: false };
                    case 5: _.label++; y = op[1]; op = [0]; continue;
                    case 7: op = _.ops.pop(); _.trys.pop(); continue;
                    default:
                        if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                        if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                        if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                        if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                        if (t[2]) _.ops.pop();
                        _.trys.pop(); continue;
                }
                op = body.call(thisArg, _);
            } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
            if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
        }
    };
    Object.defineProperty(exports, "__esModule", { value: true });





    var TAG = 'DataLogger';
    /**
     * Experimental data logger class
     *
     * @experimental
     */
    var DataLogger = /** @class */ (function () {
        function DataLogger(tap, converter, options) {
            if (converter === void 0) { converter = new DataLogPacketConverter(); }
            this.tap = tap;
            this.converter = converter;
            this.options = options;
            this.source = rxjs.interval(this.options.period);
        }
        DataLogger.fromTap = function (tap, options) {
            var converter = DataLogPacketConverter.createFromManager(tap.bundles, tap.variables);
            return new DataLogger(tap, converter, options);
        };
        DataLogger.prototype.dequeue = function () {
            return __awaiter(this, void 0, void 0, function () {
                var singlePacketResponse, singlePacket;
                return __generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, this.tap.service.datalog.dequeueOnePacket()];
                        case 1:
                            singlePacketResponse = _a.sent();
                            singlePacketResponse.successful();
                            singlePacket = singlePacketResponse.body();
                            try {
                                return [2 /*return*/, this.converter.decode({
                                        raw: singlePacketResponse.rawBody(),
                                        singlePacket: singlePacket
                                    })];
                            }
                            catch (err) {
                                throw new DataLogger.CannotDecodePacketError(singlePacket, err);
                            }
                            return [2 /*return*/];
                    }
                });
            });
        };
        DataLogger.prototype.getPacketCount = 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.datalog.getPacketCount()];
                        case 1: return [2 /*return*/, (_a.sent()).body()];
                    }
                });
            });
        };
        DataLogger.prototype.download = function () {
            var _this = this;
            return this.source.pipe(operators.flatMap(function () { return rxjs.from(_this.dequeue()); })).pipe(operators.map(function (datalogPacket, index) {
                try {
                    return {
                        type: 'progress',
                        payload: {
                            index: index,
                            limit: undefined,
                            current: datalogPacket
                        }
                    };
                }
                catch (err) {
                    return {
                        type: 'error',
                        error: err
                    };
                }
            }), operators.share());
        };
        return DataLogger;
    }());
    exports.DataLogger = DataLogger;
    (function (DataLogger) {
        var CannotDecodePacketError = /** @class */ (function (_super) {
            __extends(CannotDecodePacketError, _super);
            function CannotDecodePacketError(singlePacket, cause) {
                var _this = _super.call(this, "Cannot parse data log packet. Error: " + cause.message) || this;
                _this.singlePacket = singlePacket;
                _this.cause = cause;
                return _this;
            }
            return CannotDecodePacketError;
        }(Error));
        DataLogger.CannotDecodePacketError = CannotDecodePacketError;
    })(DataLogger = exports.DataLogger || (exports.DataLogger = {}));
    exports.DataLogger = DataLogger;
    /**
     *
     * @experimental
     */
    var RawPacketConverter = /** @class */ (function () {
        function RawPacketConverter(tlvConverter, bundleConverter, singlePacketConverter) {
            if (tlvConverter === void 0) { tlvConverter = new impl.TLVConverter(); }
            if (bundleConverter === void 0) { bundleConverter = new deviceClient.TlvBundleConverter(); }
            if (singlePacketConverter === void 0) { singlePacketConverter = new deviceClient.SinglePacketConverter(); }
            this.tlvConverter = tlvConverter;
            this.bundleConverter = bundleConverter;
            this.singlePacketConverter = singlePacketConverter;
        }
        RawPacketConverter.prototype.encode = function (data) {
            throw new Error('Method not implemented.');
        };
        RawPacketConverter.prototype.decode = function (data) {
            var tlvTree = this.tlvConverter.decode(data);
            var bundleId = tlvTree.header.id;
            // console.log(tlvTree);
            var variables = tlvTree.children
                ? this.bundleConverter.decode(tlvTree)
                : {};
            return {
                _raw: data,
                bundle: {
                    id: bundleId
                },
                rawVariables: variables
            };
        };
        return RawPacketConverter;
    }());
    exports.RawPacketConverter = RawPacketConverter;
    /**
     *
     * @experimental
     */
    var DataLogPacketConverter = /** @class */ (function () {
        function DataLogPacketConverter(meta, rawPacketConverter) {
            if (rawPacketConverter === void 0) { rawPacketConverter = new RawPacketConverter(); }
            this.meta = meta;
            this.rawPacketConverter = rawPacketConverter;
        }
        DataLogPacketConverter.createFromManager = function (bundleManager, variableManager) {
            var meta = [];
            var variableConfig = variableManager.variableConfig;
            for (var bundleId in bundleManager.bundles) {
                var bundle = bundleManager.get(bundleId);
                meta.push({
                    id: bundle.bundleId,
                    name: bundle.identifier,
                    variables: variableConfig
                });
            }
            // debug(TAG, 'Created with meta', meta );
            return new DataLogPacketConverter(meta);
        };
        DataLogPacketConverter.createFromMeta = function (meta, rawPacketConverter) {
            if (rawPacketConverter === void 0) { rawPacketConverter = new RawPacketConverter(); }
            return new DataLogPacketConverter(meta, rawPacketConverter);
        };
        DataLogPacketConverter.prototype.encode = function (type) {
            throw new Error('Method not implemented.');
        };
        DataLogPacketConverter.prototype.decode = function (data) {
            var singlePacket = data.singlePacket;
            var dataLogPacket = this.rawPacketConverter.decode(singlePacket.payload.data);
            var timeOffset = Date.now() - singlePacket.sendTime * 1000;
            dataLogPacket.bundle.logTime = new Date(singlePacket.payload.logTime * 1000 + timeOffset);
            var packet = populateDataLogPacket(dataLogPacket, this.meta || []);
            return {
                packet: packet,
                rawSinglePacket: data.raw,
                singlePacket: singlePacket
            };
        };
        return DataLogPacketConverter;
    }());
    exports.DataLogPacketConverter = DataLogPacketConverter;
    /**
     *
     * @experimental
     */
    function populateDataLogPacket(rawDataLogPacket, meta) {
        // console.log('decodeDataLogPacket', meta)
        var result = rawDataLogPacket;
        result.variables = {};
        var bundleMeta = meta.find(function (item) { return item.id == rawDataLogPacket.bundle.id; });
        if (bundleMeta) {
            var variableMeta = bundleMeta.variables;
            result.bundle.name = bundleMeta.name;
            var id_1;
            for (id_1 in rawDataLogPacket.rawVariables) {
                var data = rawDataLogPacket.rawVariables[id_1];
                var variableConfig = variableMeta.find(function (v) { return v.id == parseInt(id_1); });
                if (variableConfig) {
                    var key = variableConfig.name || variableConfig.id.toString();
                    debug.debug(TAG, 'Converting key', id_1, key, data, variableConfig);
                    result.variables[key] = variableConfig.converter
                        ? variableConfig.converter.decode(data)
                        : data; // Converts Buffer to a value according to variableConfig
                }
                else {
                    debug.debug(TAG, 'No converter available', id_1, data, variableConfig);
                    result.variables[id_1] = data;
                }
            }
        }
        else {
            debug.debug(TAG, "NO BUNDLE META FOR VARIABLE ID \"" + rawDataLogPacket.bundle.id + "\". Available:", meta.map(function (item) { return item.id; }).join(','));
        }
        if (Object.keys(result.variables).length === 0) {
            result.variables = result.rawVariables;
        }
        return result;
    }
    exports.populateDataLogPacket = populateDataLogPacket;

    });

    var dataLogger$1 = unwrapExports(dataLogger);
    var dataLogger_1 = dataLogger.DataLogger;
    var dataLogger_2 = dataLogger.RawPacketConverter;
    var dataLogger_3 = dataLogger.DataLogPacketConverter;
    var dataLogger_4 = dataLogger.populateDataLogPacket;

    var tapExtension = createCommonjsModule(function (module, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });


    Object.defineProperty(deviceClient.IoTizeDevice.prototype, 'datalogger', {
        get: function () {
            if (!this._datalogger) {
                this._datalogger = dataLogger.DataLogger.fromTap(this, {
                    period: 100 // TODO remove..
                });
            }
            return this._datalogger;
        },
        enumerable: false,
        configurable: true
    });
    deviceClient.IoTizeDevice.prototype.hasDatalogger = function () {
        return Boolean(this._datalogger);
    };

    });

    var tapExtension$1 = unwrapExports(tapExtension);

    var public_api = createCommonjsModule(function (module, exports) {
    "use strict";
    function __export(m) {
        for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
    }
    Object.defineProperty(exports, "__esModule", { value: true });
    __export(dataLogger);


    });

    var public_api$1 = unwrapExports(public_api);

    var iotizeDeviceClient_jsDatalog = createCommonjsModule(function (module, exports) {
    "use strict";
    /**
     * Generated bundle index. Do not edit.
     */
    function __export(m) {
        for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
    }
    Object.defineProperty(exports, "__esModule", { value: true });
    __export(public_api);

    });

    var iotizeDeviceClient_jsDatalog$1 = unwrapExports(iotizeDeviceClient_jsDatalog);

    return iotizeDeviceClient_jsDatalog$1;

})));
//# sourceMappingURL=iotize-device-client.js-datalog.umd.js.map
