"use strict";
/* IMPORT */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = __importDefault(require("./utils"));
const watcher_stats_1 = __importDefault(require("./watcher_stats"));
/* WATCHER POLLER */
class WatcherPoller {
    constructor() {
        /* VARIABLES */
        this.inos = {};
        this.stats = new Map();
    }
    /* API */
    getIno(targetPath, event, type) {
        const inos = this.inos[event];
        if (!inos)
            return;
        const ino = inos[targetPath];
        if (!ino)
            return;
        if (type && ino[1] !== type)
            return;
        return ino[0];
    }
    getStats(targetPath) {
        return this.stats.get(targetPath);
    }
    async poll(targetPath, timeout) {
        const stats = await utils_1.default.fs.poll(targetPath, timeout);
        if (!stats)
            return;
        const isSupported = stats.isFile() || stats.isDirectory();
        if (!isSupported)
            return;
        return new watcher_stats_1.default(stats);
    }
    reset() {
        this.inos = {};
        this.stats = new Map();
    }
    async update(targetPath, timeout) {
        const prev = this.getStats(targetPath), next = await this.poll(targetPath, timeout);
        this.updateStats(targetPath, next);
        if (!prev && next) {
            if (next.isFile()) {
                this.updateIno(targetPath, "add" /* ADD */, next);
                return ["add" /* ADD */];
            }
            if (next.isDirectory()) {
                this.updateIno(targetPath, "addDir" /* ADD_DIR */, next);
                return ["addDir" /* ADD_DIR */];
            }
        }
        else if (prev && !next) {
            if (prev.isFile()) {
                this.updateIno(targetPath, "unlink" /* UNLINK */, prev);
                return ["unlink" /* UNLINK */];
            }
            if (prev.isDirectory()) {
                this.updateIno(targetPath, "unlinkDir" /* UNLINK_DIR */, prev);
                return ["unlinkDir" /* UNLINK_DIR */];
            }
        }
        else if (prev && next) {
            if (prev.isFile()) {
                if (next.isFile()) {
                    if (prev.ino === next.ino && !prev.size && !next.size)
                        return []; // Same path, same content and same file, nothing actually changed
                    this.updateIno(targetPath, "change" /* CHANGE */, next);
                    return ["change" /* CHANGE */];
                }
                if (next.isDirectory()) {
                    this.updateIno(targetPath, "unlink" /* UNLINK */, prev);
                    this.updateIno(targetPath, "addDir" /* ADD_DIR */, next);
                    return ["unlink" /* UNLINK */, "addDir" /* ADD_DIR */];
                }
            }
            else if (prev.isDirectory()) {
                if (next.isFile()) {
                    this.updateIno(targetPath, "unlinkDir" /* UNLINK_DIR */, prev);
                    this.updateIno(targetPath, "add" /* ADD */, next);
                    return ["unlinkDir" /* UNLINK_DIR */, "add" /* ADD */];
                }
                if (next.isDirectory()) {
                    if (prev.ino === next.ino)
                        return []; // Same path and same directory, nothing actually changed
                    this.updateIno(targetPath, "unlinkDir" /* UNLINK_DIR */, prev);
                    this.updateIno(targetPath, "addDir" /* ADD_DIR */, next);
                    return ["unlinkDir" /* UNLINK_DIR */, "addDir" /* ADD_DIR */];
                }
            }
        }
        return [];
    }
    updateIno(targetPath, event, stats) {
        const inos = this.inos[event] = this.inos[event] || (this.inos[event] = {}), type = stats.isFile() ? 2 /* FILE */ : 1 /* DIR */;
        inos[targetPath] = [stats.ino, type];
    }
    updateStats(targetPath, stats) {
        if (stats) {
            this.stats.set(targetPath, stats);
        }
        else {
            this.stats.delete(targetPath);
        }
    }
}
/* EXPORT */
exports.default = WatcherPoller;
//# sourceMappingURL=data:application/json;base64,[encoded data, 4580 characters]