"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
/**
 * penguins-eggs
 * command: syncfrom.ts
 * author: Piero Proietti
 * email: piero.proietti@gmail.com
 * license: MIT
 */
const core_1 = require("@oclif/core");
const fs_1 = tslib_1.__importDefault(require("fs"));
const path_1 = tslib_1.__importDefault(require("path"));
const utils_1 = tslib_1.__importDefault(require("../classes/utils"));
const utils_2 = require("../lib/utils");
/**
 *
 */
class Syncfrom extends core_1.Command {
    constructor() {
        super(...arguments);
        this.verbose = false;
        this.echo = {};
        this.rootDir = '/';
        this.luksName = 'luks-eggs-data';
        this.luksFile = `/run/live/medium/live/${this.luksName}`;
        this.luksDevice = `/dev/mapper/${this.luksName}`;
        this.luksMountpoint = '/tmp/eggs-data';
    }
    async run() {
        const { flags } = await this.parse(Syncfrom);
        if (flags.verbose) {
            this.verbose = true;
        }
        this.echo = utils_1.default.setEcho(this.verbose);
        let fileVolume = '';
        if (flags.file) {
            fileVolume = flags.file;
        }
        let destDelete = false;
        if (flags.delete) {
            destDelete = true;
        }
        if (utils_1.default.isLive()) {
            if (flags.rootdir) {
                this.rootDir = flags.rootdir;
            }
            else {
                utils_1.default.pressKeyToExit('Argument --rootdir is mandatory, when running live! Process will terminate');
            }
        }
        if (utils_1.default.isRoot()) {
            if (fileVolume === '') {
                fileVolume = '/run/live/medium/live/luks-eggs-dada';
            }
            if (!utils_1.default.isLive()) {
                /**
                 * WORKING FROM INSTALLED
                 */
                if (fs_1.default.existsSync(fileVolume)) {
                    this.luksName = path_1.default.basename(fileVolume);
                    this.luksFile = fileVolume;
                    this.luksDevice = `/dev/mapper/${this.luksName}`;
                    this.luksMountpoint = '/tmp/eggs-data';
                    await this.restorePrivateData();
                    if (await utils_1.default.customConfirm('Your system was updated! Press a key to reboot')) {
                        await (0, utils_2.exec)('reboot');
                    }
                }
                else {
                    utils_1.default.pressKeyToExit(`Can't find ${this.luksFile}`);
                }
            }
            else {
                /**
                 * WORKING FROM LIVE
                 */
                this.luksName = path_1.default.basename(fileVolume);
                this.luksFile = fileVolume;
                this.luksDevice = `/dev/mapper/${this.luksName}`;
                this.luksMountpoint = '/tmp/eggs-data';
                await this.restorePrivateData();
            }
        }
        else {
            utils_1.default.useRoot(this.id);
        }
    }
    /**
     *
     * @param verbose
     */
    async restorePrivateData(destDelete = false) {
        if (!fs_1.default.existsSync(this.luksMountpoint)) {
            await (0, utils_2.exec)(`mkdir ${this.luksMountpoint}`, this.echo);
        }
        await this.luksOpen();
        /**
         * ONLY FROM LIVE
         * rm home, subst /etc/passwd, /etc/shadow, /etc/groups
         */
        if (utils_1.default.isLive() && this.rootDir !== '/') {
            utils_1.default.warning('Removing live user on destination system');
            await (0, utils_2.exec)(`rm -rf ${this.rootDir}/home/*`, this.echo);
            utils_1.default.warning('Restoring accounts');
            await (0, utils_2.exec)(`cp ${this.luksMountpoint}/etc/passwd ${this.rootDir}/etc/`, this.echo);
            await (0, utils_2.exec)(`cp ${this.luksMountpoint}/etc/shadow ${this.rootDir}/etc/`, this.echo);
            await (0, utils_2.exec)(`cp ${this.luksMountpoint}/etc/group ${this.rootDir}/etc/`, this.echo);
        }
        utils_1.default.warning('Restoring crypted data');
        let cmd = `rsync -a ${this.luksMountpoint}/ROOT/ ${this.rootDir}/`;
        if (destDelete) {
            cmd = `rsync --archive --delete ${this.luksMountpoint}/ROOT/ ${this.rootDir}/`;
        }
        await (0, utils_2.exec)(cmd, this.echo);
        await this.luksClose();
    }
    /**
     *
     */
    async luksOpen() {
        if (!fs_1.default.existsSync(this.luksDevice)) {
            utils_1.default.warning(`LUKS open volume: ${this.luksName}`);
            await (0, utils_2.exec)(`cryptsetup luksOpen --type luks2 ${this.luksFile} ${this.luksName}`, utils_1.default.setEcho(true));
        }
        else {
            utils_1.default.warning(`LUKS volume: ${this.luksName} already open`);
        }
        if (!fs_1.default.existsSync(this.luksMountpoint)) {
            await (0, utils_2.exec)(`mkdir -p ${this.luksMountpoint}`, this.echo);
        }
        if (!utils_1.default.isMountpoint(this.luksMountpoint)) {
            utils_1.default.warning(`mount volume: ${this.luksDevice} on ${this.luksMountpoint}`);
            await (0, utils_2.exec)(`mount ${this.luksDevice} ${this.luksMountpoint}`, this.echo);
        }
        else {
            utils_1.default.warning(`mount volume: ${this.luksDevice} already mounted on ${this.luksMountpoint}`);
        }
    }
    /**
    *
    */
    async luksClose() {
        if (utils_1.default.isMountpoint(this.luksMountpoint)) {
            await (0, utils_2.exec)(`umount ${this.luksMountpoint}`, this.echo);
        }
        if (fs_1.default.existsSync(this.luksDevice)) {
            utils_1.default.warning(`LUKS close volume: ${this.luksName}`);
            await (0, utils_2.exec)(`cryptsetup luksClose ${this.luksName}`, this.echo);
        }
    }
}
Syncfrom.flags = {
    delete: core_1.Flags.string({ description: 'rsync --delete delete extraneous files from dest dirs' }),
    file: core_1.Flags.string({ char: 'f', description: 'file LUKS volume encrypted' }),
    help: core_1.Flags.help({ char: 'h' }),
    rootdir: core_1.Flags.string({ char: 'r', description: 'rootdir of the installed system, when used from live' }),
    verbose: core_1.Flags.boolean({ char: 'v', description: 'verbose' }),
};
Syncfrom.description = 'restore users and user data from a LUKS volumes';
Syncfrom.examples = [
    'sudo eggs syncfrom',
    'sudo eggs syncfrom --file /path/to/fileLUKS',
];
exports.default = Syncfrom;
