"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectBackupService = void 0;
const yok_1 = require("../common/yok");
const path = require("path");
const color_1 = require("../color");
class ProjectBackupService {
    constructor($fs, $logger, $projectHelper) {
        this.$fs = $fs;
        this.$logger = $logger;
        this.$projectHelper = $projectHelper;
    }
    getBackup(backupName) {
        return new ProjectBackupService.Backup(this, backupName);
    }
    backup(name, pathsToBackup) {
        const backup = new ProjectBackupService.Backup(this, name, pathsToBackup);
        return backup.create();
    }
    restore(name) {
        const backup = new ProjectBackupService.Backup(this, name);
        return backup.restore();
    }
}
ProjectBackupService.Backup = class Backup {
    constructor($super, name, pathsToBackup = [], basePath = $super.$projectHelper.projectDir) {
        this.$super = $super;
        this.name = name;
        this.pathsToBackup = pathsToBackup;
        this.basePath = basePath;
    }
    get backupDir() {
        return path.resolve(this.basePath, `.${this.name}_backup`);
    }
    create() {
        const backupData = this.getBackupData();
        const backedUpPaths = (backupData === null || backupData === void 0 ? void 0 : backupData.paths) || [];
        this.$super.$logger.trace("creating backup: ", this.name);
        this.$super.$fs.createDirectory(this.backupDir);
        for (const pathToBackup of this.pathsToBackup) {
            const sourcePath = path.resolve(this.basePath, pathToBackup);
            const targetPath = path.resolve(this.backupDir, pathToBackup);
            if (this.$super.$fs.exists(sourcePath)) {
                this.$super.$logger.trace(`BACKING UP ${color_1.color.cyan(sourcePath)} -> ${color_1.color.green(targetPath)}`);
                this.$super.$fs.copyFile(sourcePath, targetPath);
                backedUpPaths.push(pathToBackup);
            }
        }
        // create backup.json
        this.$super.$fs.writeJson(path.resolve(this.backupDir, "_backup.json"), {
            name: this.name,
            paths: backedUpPaths,
        });
        return this;
    }
    restore() {
        const backupData = this.getBackupData();
        if (!backupData) {
            return this;
        }
        for (const pathToBackup of backupData.paths) {
            const sourcePath = path.resolve(this.backupDir, pathToBackup);
            const targetPath = path.resolve(this.basePath, pathToBackup);
            this.$super.$logger.trace(`RESTORING ${color_1.color.green(sourcePath)} -> ${color_1.color.cyan(targetPath)}`);
            if (this.$super.$fs.exists(sourcePath)) {
                this.$super.$fs.copyFile(sourcePath, targetPath);
            }
        }
        this.$super.$logger.trace(backupData);
        // restore files
        return this;
    }
    isUpToDate() {
        const backupData = this.getBackupData();
        if (!backupData) {
            return false;
        }
        for (const pathToBackup of backupData.paths) {
            const sourcePath = path.resolve(this.backupDir, pathToBackup);
            // if any of the files don't exist the backup is not up-to-date
            if (!this.$super.$fs.exists(sourcePath)) {
                return false;
            }
        }
        return true;
    }
    remove() {
        if (!this.$super.$fs.exists(this.backupDir)) {
            this.$super.$logger.trace(`No backup named ${this.name} could be found.`);
            return;
        }
        this.$super.$fs.deleteDirectory(this.backupDir);
        return this;
    }
    addPath(backupPath) {
        this.pathsToBackup.push(path.relative(this.basePath, backupPath));
        return this;
    }
    addPaths(backupPaths) {
        backupPaths.forEach(this.addPath.bind(this));
        return this;
    }
    getBackupData() {
        if (!this.$super.$fs.exists(this.backupDir)) {
            this.$super.$logger.trace(`No backup named ${this.name} could be found.`);
            return;
        }
        const backupJSONPath = path.resolve(this.backupDir, "_backup.json");
        if (!this.$super.$fs.exists(backupJSONPath)) {
            this.$super.$logger.trace(`The backup ${this.name} does not contain a _backup.json.`);
            return;
        }
        return this.$super.$fs.readJson(backupJSONPath);
    }
};
exports.ProjectBackupService = ProjectBackupService;
yok_1.injector.register("projectBackupService", ProjectBackupService);
//# sourceMappingURL=project-backup-service.js.map