"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const JSONStream = require("json-stream");
const events_1 = require("events");
class ResourceWatcher extends events_1.EventEmitter {
    constructor(config) {
        super();
        this.api = config.api;
        this.qs = config.qs || {};
        this.logger = config.logger;
    }
    start(resourceVersion) {
        return __awaiter(this, void 0, void 0, function* () {
            const qs = Object.assign({}, this.qs, { watch: true, resourceVersion });
            this.stream = this.api.getStream({ qs });
            this.currentResourceVersion = resourceVersion;
            this.stream.on("end", (err) => {
                this.logger.info("Watch stream ended, restarting");
                delete this.stream;
                delete this.jsonStream;
                this.start(this.currentResourceVersion);
            });
            this.stream.on("error", (err) => {
                this.logger.warn(`Watch stream error, restarting. ${err}`);
                delete this.stream;
                delete this.jsonStream;
                this.start(this.currentResourceVersion);
            });
            this.jsonStream = new JSONStream();
            this.stream.pipe(this.jsonStream);
            this.jsonStream.on("data", (event) => __awaiter(this, void 0, void 0, function* () {
                if (event.type === "ERROR") {
                    yield this.stop();
                }
                else {
                    this.currentResourceVersion = event.object.metadata.resourceVersion;
                }
                this.emit(event.type.toLowerCase(), event.object);
            }));
        });
    }
    stop() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.stream) {
                this.stream.removeAllListeners();
                delete this.stream;
            }
            if (this.jsonStream) {
                delete this.jsonStream;
            }
        });
    }
}
exports.ResourceWatcher = ResourceWatcher;
//# sourceMappingURL=ResourceWatcher.js.map