"use strict";
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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectCleanupService = void 0;
const yok_1 = require("../common/yok");
const path = require("path");
const color_1 = require("../color");
class ProjectCleanupService {
    constructor($fs, $logger, $projectHelper, $terminalSpinnerService) {
        this.$fs = $fs;
        this.$logger = $logger;
        this.$projectHelper = $projectHelper;
        this.$terminalSpinnerService = $terminalSpinnerService;
    }
    clean(pathsToClean, options) {
        return __awaiter(this, void 0, void 0, function* () {
            this.spinner = this.$terminalSpinnerService.createSpinner({
                isSilent: options === null || options === void 0 ? void 0 : options.silent,
            });
            let stats = (options === null || options === void 0 ? void 0 : options.stats) ? new Map() : false;
            let success = true;
            for (const pathToClean of pathsToClean) {
                const cleanRes = yield this.cleanPath(pathToClean, options).catch((error) => {
                    this.$logger.trace(`Encountered error while cleaning. Error is: ${error.message}.`, error);
                    return { ok: false };
                });
                if (stats && "size" in cleanRes) {
                    stats.set(pathToClean, cleanRes.size);
                }
                success = success && cleanRes.ok;
            }
            if (!(options === null || options === void 0 ? void 0 : options.silent)) {
                // required to print an empty line for the spinner to not replace the last status... (probably a bug in the spinners)
                console.log();
            }
            if (stats) {
                return { ok: success, stats };
            }
            return { ok: success };
        });
    }
    cleanPath(pathToClean, options) {
        var _a;
        return __awaiter(this, void 0, void 0, function* () {
            const dryRun = (_a = options === null || options === void 0 ? void 0 : options.dryRun) !== null && _a !== void 0 ? _a : false;
            const logPrefix = dryRun ? color_1.color.grey("(dry run) ") : "";
            this.spinner.clear();
            let fileType;
            if (!pathToClean || pathToClean.trim().length === 0) {
                this.$logger.trace(`${logPrefix}cleanPath called with no pathToClean.`);
                return { ok: true };
            }
            const filePath = path.resolve(this.$projectHelper.projectDir, pathToClean);
            const displayPath = color_1.color.yellow(`${path.relative(this.$projectHelper.projectDir, filePath)}`);
            this.$logger.trace(`${logPrefix}Trying to clean '${filePath}'`);
            if (this.$fs.exists(filePath)) {
                const stat = this.$fs.getFsStats(filePath);
                let size = 0;
                if (options === null || options === void 0 ? void 0 : options.stats) {
                    size = this.$fs.getSize(filePath);
                }
                if (stat.isDirectory()) {
                    this.$logger.trace(`${logPrefix}Path '${filePath}' is a directory, deleting.`);
                    !dryRun && this.$fs.deleteDirectorySafe(filePath);
                    fileType = "directory";
                }
                else {
                    this.$logger.trace(`${logPrefix}Path '${filePath}' is a file, deleting.`);
                    !dryRun && this.$fs.deleteFile(filePath);
                    fileType = "file";
                }
                const success = dryRun || !this.$fs.exists(filePath);
                if (success) {
                    this.spinner.succeed(`${logPrefix}Cleaned ${fileType} ${displayPath}`);
                }
                else {
                    const message = color_1.color.red(`Failed to Clean ${fileType}`);
                    this.spinner.fail(`${logPrefix}${message} ${displayPath}`);
                }
                if (options === null || options === void 0 ? void 0 : options.stats) {
                    return { ok: success, size };
                }
                return { ok: success };
            }
            this.$logger.trace(`${logPrefix}Path '${filePath}' not found, skipping.`);
            this.spinner.info(`${logPrefix}Skipping ${displayPath} because it doesn't exist.`);
            if (options === null || options === void 0 ? void 0 : options.stats) {
                return { ok: true, size: 0 };
            }
            return { ok: true };
        });
    }
}
exports.ProjectCleanupService = ProjectCleanupService;
yok_1.injector.register("projectCleanupService", ProjectCleanupService);
//# sourceMappingURL=project-cleanup-service.js.map