"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
const path_1 = tslib_1.__importDefault(require("path"));
const parse_diff_1 = tslib_1.__importDefault(require("parse-diff"));
const promise_1 = tslib_1.__importDefault(require("simple-git/promise"));
const logger_1 = tslib_1.__importDefault(require("./logger"));
const constants_1 = require("../constants");
// Interface for running git commands.
// https://github.com/steveukx/git-js
exports.git = promise_1.default();
/**
 * Store diff of all commits.
 */
async function storeDiff(commits) {
    const diffPromises = commits.map(async (commit) => {
        const command = ['show', '-U99999', commit];
        const output = await exports.git.raw(command);
        const diffText = output
            .replace(/\\ No newline at end of file\n/g, '')
            .split('\n\n')
            .slice(-1)[0];
        const diff = parse_diff_1.default(diffText);
        return { commit, diff };
    });
    const diffs = await Promise.all(diffPromises);
    fs_extra_1.default.writeFileSync(path_1.default.join(constants_1.TUTURE_ROOT, 'diff.json'), JSON.stringify(diffs));
    return diffs;
}
exports.storeDiff = storeDiff;
/**
 * Append .tuture rule to gitignore.
 * If it's already ignored, do nothing.
 * If .gitignore doesn't exist, create one and add the rule.
 * @param config User config
 */
function appendGitignore(config) {
    const ignoreRules = [
        '# Tuture-related files\n',
        constants_1.TUTURE_ROOT,
        config.buildPath,
    ].join('\n');
    if (!fs_extra_1.default.existsSync('.gitignore')) {
        fs_extra_1.default.writeFileSync('.gitignore', `${ignoreRules}\n`);
        logger_1.default.log('info', '.gitignore file created.');
    }
    else if (!fs_extra_1.default
        .readFileSync('.gitignore')
        .toString()
        .includes(constants_1.TUTURE_ROOT)) {
        fs_extra_1.default.appendFileSync('.gitignore', `\n${ignoreRules}`);
        logger_1.default.log('info', '.gitignore rules appended.');
    }
}
exports.appendGitignore = appendGitignore;
/**
 * Infer github field from available information.
 */
async function inferGithubField() {
    let github = '';
    try {
        // Trying to infer github repo url from origin.
        const remote = await exports.git.remote([]);
        if (remote) {
            const origin = await exports.git.remote(['get-url', remote]);
            if (origin) {
                github = origin.replace('.git', '').trim();
            }
        }
    }
    catch (_a) {
        // No remote url, infer github field from git username and cwd.
        let username = await exports.git.raw(['config', '--get', 'user.name']);
        if (!username) {
            username = await exports.git.raw(['config', '--global', '--get', 'user.name']);
        }
        if (username) {
            const { name: repoName } = path_1.default.parse(process.cwd());
            github = `https://github.com/${username.trim()}/${repoName}`;
        }
    }
    return github;
}
exports.inferGithubField = inferGithubField;
/**
 * Generate Git hook for different platforms.
 */
function getGitHook() {
    let tuturePath = path_1.default.join(__dirname, '..', '..', 'bin', 'run');
    if (process.platform === 'win32') {
        // Replace all \ with / in the path, as is required in Git hook on windows
        // e.g. C:\foo\bar => C:/foo/bar
        tuturePath = tuturePath.replace(/\\/g, '/');
    }
    return `#!/bin/sh\n${tuturePath} reload\n`;
}
/**
 * Add post-commit Git hook for reloading.
 */
function appendGitHook() {
    const reloadHook = getGitHook();
    const hookPath = path_1.default.join('.git', 'hooks', 'post-commit');
    if (!fs_extra_1.default.existsSync(hookPath)) {
        fs_extra_1.default.mkdirpSync(path_1.default.dirname(hookPath));
        fs_extra_1.default.writeFileSync(hookPath, reloadHook, { mode: 0o755 });
        logger_1.default.log('info', 'Git post-commit hook added.');
    }
    else if (!fs_extra_1.default
        .readFileSync(hookPath)
        .toString()
        .includes('reload')) {
        fs_extra_1.default.appendFileSync(hookPath, reloadHook);
        logger_1.default.log('info', 'Git post-commit hook configured.');
    }
}
exports.appendGitHook = appendGitHook;
/**
 * Remove Git hook for reloading.
 */
function removeGitHook() {
    const reloadHook = getGitHook();
    const hookPath = path_1.default.join('.git', 'hooks', 'post-commit');
    if (fs_extra_1.default.existsSync(hookPath)) {
        const hook = fs_extra_1.default.readFileSync(hookPath).toString();
        if (hook === reloadHook) {
            // Auto-generated by Tuture, so delete it.
            fs_extra_1.default.removeSync(hookPath);
        }
        else {
            fs_extra_1.default.writeFileSync(hookPath, hook.replace('tuture reload', ''));
        }
        logger_1.default.log('info', 'Git post-commit hook removed.');
    }
}
exports.removeGitHook = removeGitHook;
