var __awaiter = (this && this.__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 = (this && this.__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 };
    }
};
import '@iotize/tap/service/impl/data-log';
import { isCodeError } from '@iotize/common/error';
import { TapError } from '@iotize/tap';
import { ResultCode } from '@iotize/tap/client/api';
import { TlvBundleConverter, TLVConverter } from '@iotize/tap/client/impl';
import { interval } from 'rxjs';
import { map, share, switchMap } from 'rxjs/operators';
import { DataLoggerError } from './errors';
var TAG = 'DataLogger';
/**
 * Experimental data logger class
 *
 * @experimental
 */
var DataLogger = /** @class */ (function () {
    function DataLogger(tap, converter) {
        if (converter === void 0) { converter = new DataLogSinglePacketToDataLogPacketConverter(); }
        this.tap = tap;
        this.converter = converter;
    }
    // public static fromTap(tap: Tap, options: DataLogger.Options) {
    //     const converter = DataLogPacketConverter.createFromManager(
    //         tap.bundles,
    //         tap.variables
    //     );
    //     return new DataLogger(tap, converter, options);
    // }
    DataLogger.prototype.isAcquisitionRunning = 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.isRunning()];
                    case 1: return [2 /*return*/, (_a.sent()).body()];
                }
            });
        });
    };
    DataLogger.prototype.startAcquisition = function () {
        return __awaiter(this, void 0, void 0, function () {
            var err_1, statusCode;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        _a.trys.push([0, 2, , 3]);
                        return [4 /*yield*/, this.tap.service.dataLog.run()];
                    case 1:
                        (_a.sent()).successful();
                        return [3 /*break*/, 3];
                    case 2:
                        err_1 = _a.sent();
                        if (isCodeError(TapError.Code.ResponseStatusError, err_1)) {
                            statusCode = err_1.response.status;
                            if (statusCode === ResultCode.UNAUTHORIZED) {
                                throw DataLoggerError.notAuthorizedToPerformAction("You are not authorized to start data log acquisition. Login to perform this action", err_1);
                            }
                        }
                        throw err_1;
                    case 3: return [2 /*return*/];
                }
            });
        });
    };
    DataLogger.prototype.stopAcquisition = function () {
        return __awaiter(this, void 0, void 0, function () {
            var err_2, statusCode;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        _a.trys.push([0, 2, , 3]);
                        return [4 /*yield*/, this.tap.service.dataLog.stop()];
                    case 1:
                        (_a.sent()).successful();
                        return [3 /*break*/, 3];
                    case 2:
                        err_2 = _a.sent();
                        if (isCodeError(TapError.Code.ResponseStatusError, err_2)) {
                            statusCode = err_2.response.status;
                            if (statusCode === ResultCode.UNAUTHORIZED) {
                                throw DataLoggerError.notAuthorizedToPerformAction("You are not authorized to stop data log acquisition. Login to perform this action", err_2);
                            }
                        }
                        throw err_2;
                    case 3: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Dequeue one data log packet
     */
    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();
                        singlePacket = singlePacketResponse.body();
                        // singlePacketResponse.successful();
                        // const singlePacketFrame = singlePacketResponse.rawBody();
                        try {
                            return [2 /*return*/, this.converter.decode(singlePacket)];
                        }
                        catch (err) {
                            throw DataLoggerError.decodePacketError(singlePacket, err);
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Get stored packet count in Tap
     */
    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()];
                }
            });
        });
    };
    /**
     * Download all packets from store
     */
    DataLogger.prototype.download = function (options) {
        var _this = this;
        return interval((options === null || options === void 0 ? void 0 : options.period) || 400)
            .pipe(switchMap(function (time) { return _this.dequeue(); }), map(function (datalogPacket, index) {
            try {
                return {
                    type: 'new-packet',
                    progress: {
                        total: undefined,
                        loaded: index + 1
                    },
                    packet: datalogPacket
                };
            }
            catch (err) {
                return {
                    type: 'error',
                    error: err
                };
            }
        }), share());
    };
    return DataLogger;
}());
export { DataLogger };
/**
 *
 * @experimental
 */
var DataLogSinglePacketToDataLogPacketConverter = /** @class */ (function () {
    function DataLogSinglePacketToDataLogPacketConverter(tlvConverter, bundleConverter
    // public singlePacketConverter = new SinglePacketConverter()
    ) {
        if (tlvConverter === void 0) { tlvConverter = new TLVConverter(); }
        if (bundleConverter === void 0) { bundleConverter = new TlvBundleConverter(); }
        this.tlvConverter = tlvConverter;
        this.bundleConverter = bundleConverter;
    }
    // encode(data: SinglePacket): DataLogger.RawPacket {
    //     throw new Error('Method not implemented.');
    // }
    DataLogSinglePacketToDataLogPacketConverter.prototype.decode = function (singlePacket) {
        var data = singlePacket.payload.data;
        var tlvTree = this.tlvConverter.decode(data);
        var bundleId = tlvTree.header.id;
        // console.log(tlvTree);
        var variables = tlvTree.children
            ? this.bundleConverter.decode(tlvTree)
            : {};
        var timeOffset = Date.now() - singlePacket.sendTime * 1000;
        var logTime = new Date(singlePacket.payload.logTime * 1000 + timeOffset);
        return {
            meta: {
                packetId: singlePacket.header.packetId,
                senderId: singlePacket.header.senderId,
                bundleId: bundleId,
                logTime: logTime
            },
            data: variables
        };
    };
    return DataLogSinglePacketToDataLogPacketConverter;
}());
export { DataLogSinglePacketToDataLogPacketConverter };
/**
 *
 * @experimental
 */
// export class DataLogPacketConverter<T = Record<string, any>>
//     implements
//     EncoderDecoder<
//     DataLogger.PacketInfo<T>,
//     { raw: Uint8Array; singlePacket: SinglePacket }
//     > {
//     constructor(
//         public meta?: BundleConfig[],
//         public rawPacketConverter: RawPacketConverter = new RawPacketConverter()
//     ) { }
//     public static createFromMeta<T>(
//         meta: BundleConfig[],
//         rawPacketConverter: RawPacketConverter = new RawPacketConverter()
//     ): DataLogPacketConverter<T> {
//         return new DataLogPacketConverter(meta, rawPacketConverter);
//     }
//     encode(
//         type: DataLogger.PacketInfo<T>
//     ): { raw: Uint8Array; singlePacket: SinglePacket } {
//         throw new Error('Method not implemented.');
//     }
//     decode(data: {
//         raw: Uint8Array;
//         singlePacket: SinglePacket;
//     }): DataLogger.PacketInfo<T> {
//         const singlePacket = data.singlePacket;
//         const dataLogPacket = this.rawPacketConverter.decode(
//             singlePacket.payload.data
//         );
//         const timeOffset = Date.now() - singlePacket.sendTime * 1000;
//         dataLogPacket.bundle.logTime = new Date(
//             singlePacket.payload.logTime * 1000 + timeOffset
//         );
//         const packet = populateDataLogPacket<T>(dataLogPacket, this.meta || []);
//         return {
//             packet,
//             rawSinglePacket: data.raw,
//             singlePacket
//         };
//     }
// }
//# sourceMappingURL=data:application/json;base64, 