"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());
    });
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to set private field on non-instance");
    }
    privateMap.set(receiver, value);
    return value;
};
var _pathToThemesManifest;
Object.defineProperty(exports, "__esModule", { value: true });
const systemSettings = require("@ewizardjs/system-settings");
const fs_extra_1 = require("fs-extra");
const globby = require("globby");
const multimatch = require("multimatch");
const ramda_1 = require("ramda");
const upath_1 = require("upath");
const uniq_1 = require("../../utils/uniq");
const Archiver_1 = require("./Archiver");
const filesPattern_1 = require("./filesPattern");
const utils_1 = require("./utils");
class EmailsArchiver extends Archiver_1.default {
    constructor(presentationPath, options) {
        super(presentationPath, options);
        this.presentationPath = presentationPath;
        this.options = options;
        _pathToThemesManifest.set(this, void 0);
    }
    getPathToThemesManifest() {
        return __awaiter(this, void 0, void 0, function* () {
            if (__classPrivateFieldGet(this, _pathToThemesManifest)) {
                return __classPrivateFieldGet(this, _pathToThemesManifest);
            }
            const { themes, themesManifest } = yield systemSettings.getByPath(this.presentationPath, 'path');
            __classPrivateFieldSet(this, _pathToThemesManifest, {
                themes,
                themesManifest: upath_1.dirname(themesManifest) === '.' ? upath_1.join(themes, themesManifest) : themesManifest,
            });
            return __classPrivateFieldGet(this, _pathToThemesManifest);
        });
    }
    getRequiredFiles() {
        return __awaiter(this, void 0, void 0, function* () {
            const [requiredFiles, { themesManifest }] = yield Promise.all([
                globby(filesPattern_1.REQUIRED_FILES_PATTERNS, { cwd: this.presentationPath, dot: true }),
                this.getPathToThemesManifest(),
            ]);
            requiredFiles.push(themesManifest);
            return requiredFiles;
        });
    }
    collectRedundantThemesPatterns() {
        return __awaiter(this, void 0, void 0, function* () {
            const { themes, themesManifest } = yield this.getPathToThemesManifest();
            const fullPath = upath_1.join(this.presentationPath, themesManifest);
            try {
                const themesList = yield fs_extra_1.readJSON(fullPath);
                const themesFolders = themesList.themes.map((theme) => upath_1.join(themes, theme.id));
                return [
                    `${upath_1.join(themes, '**', '*')}`,
                    `!${upath_1.join(themes, '*.json')}`,
                    ...themesFolders.map((folder) => upath_1.join(`!${folder}`, '**', '*')),
                ];
            }
            catch (_a) {
                return [];
            }
        });
    }
    collectRedundantBlocksPatterns() {
        return __awaiter(this, void 0, void 0, function* () {
            const { blocks, blocksManifest } = (yield systemSettings.get(this.presentationPath)).path;
            const fullPath = upath_1.join(this.presentationPath, blocksManifest);
            try {
                const blocksjson = yield fs_extra_1.readJSON(fullPath);
                const bocksFolders = blocksjson.components.map((block) => upath_1.join(blocks, block.id));
                return [
                    `${upath_1.join(blocks, '**', '*')}`,
                    `!${upath_1.join(blocks, '*.json')}`,
                    ...bocksFolders.map((folder) => upath_1.join(`!${folder}`, '**', '*')),
                ];
            }
            catch (_a) {
                return [];
            }
        });
    }
    getPatternsForRedundantFiles() {
        return __awaiter(this, void 0, void 0, function* () {
            return Promise.all([
                this.collectRedundantThemesPatterns(),
                this.collectRedundantBlocksPatterns(),
            ]);
        });
    }
    collectFilesToArchive() {
        return __awaiter(this, void 0, void 0, function* () {
            const [requiredFiles, files, redundantFilesPatternsList] = yield Promise.all([
                this.getRequiredFiles(),
                this.getFilesList(),
                this.getPatternsForRedundantFiles(),
            ]);
            const allFiles = uniq_1.default(this.options.files.concat(requiredFiles, files));
            const redundantFiles = redundantFilesPatternsList.reduce((redundantFiles, redundantFilesPatterns) => {
                const matchedFiles = multimatch(allFiles, redundantFilesPatterns, { dot: true });
                return redundantFiles.concat(matchedFiles);
            }, []);
            return ramda_1.without(redundantFiles, allFiles);
        });
    }
    getFilePatterns() {
        return __awaiter(this, void 0, void 0, function* () {
            const settings = yield systemSettings.get(this.presentationPath);
            return this.getMergedPatterns(settings === null || settings === void 0 ? void 0 : settings.archive);
        });
    }
    getMergedPatterns(archiveSettings) {
        return __awaiter(this, void 0, void 0, function* () {
            const { patterns, ignore } = archiveSettings !== null && archiveSettings !== void 0 ? archiveSettings : {};
            const monorepoPatterns = yield this.getMonorepoPatterns();
            const emailPatterns = filesPattern_1.EMAIL_FILES_PATTERN.concat(monorepoPatterns);
            if (patterns) {
                return emailPatterns.concat(patterns);
            }
            if (ignore) {
                return emailPatterns.concat(utils_1.getRevertedIgnorePatterns(ignore));
            }
            return emailPatterns;
        });
    }
    getFilesList() {
        return __awaiter(this, void 0, void 0, function* () {
            const filePatterns = yield this.getFilePatterns();
            return globby(filePatterns, { cwd: this.presentationPath, dot: true });
        });
    }
    getMonorepoPatterns() {
        return __awaiter(this, void 0, void 0, function* () {
            const { layouts, masterTemplatePath, masterTemplateLayout, } = (yield systemSettings.get(this.presentationPath)).path;
            const patterns = [];
            if (masterTemplatePath && typeof masterTemplatePath === 'string') {
                const filesPattern = '**/*.json';
                const layoutsPath = upath_1.join(masterTemplatePath, layouts);
                patterns.push(...[upath_1.join(masterTemplatePath, filesPattern), `!${upath_1.join(layoutsPath, filesPattern)}`]);
                if (masterTemplateLayout && typeof masterTemplateLayout === 'string') {
                    patterns.push(upath_1.join(layoutsPath, masterTemplateLayout, filesPattern));
                }
            }
            return patterns;
        });
    }
}
exports.default = EmailsArchiver;
_pathToThemesManifest = new WeakMap();
//# sourceMappingURL=EmailsArchiver.js.map