"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const command_1 = require("@oclif/command");
const rimraf_1 = __importDefault(require("rimraf"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const fetchWithProxy_1 = __importDefault(require("../fetchWithProxy"));
const unzipper_1 = __importDefault(require("unzipper"));
const base_1 = __importDefault(require("../base"));
class Upgrade extends base_1.default {
    async run() {
        const { args: runArgs, flags: runFlags } = this.parse(Upgrade);
        const { localPath: argsPath } = runArgs;
        const { clean, listVersions, tag, url, branch, nightly } = runFlags;
        if (listVersions) {
            const versions = (await this.fetchGithubVersions()).map(v => v.tag_name);
            this.log(`All JBrowse versions:\n${versions.join('\n')}`);
            this.exit();
        }
        this.debug(`Want to upgrade at: ${argsPath}`);
        if (!argsPath) {
            this.error(`No directory supplied`, { exit: 100 });
        }
        if (!fs_1.default.existsSync(path_1.default.join(argsPath, 'manifest.json'))) {
            this.error(`No manifest.json found in this directory, are you sure it is an
        existing jbrowse 2 installation?`, { exit: 10 });
        }
        const locationUrl = url ||
            (nightly ? await this.getBranch('main') : '') ||
            (branch ? await this.getBranch(branch) : '') ||
            (tag ? await this.getTag(tag) : await this.getLatest());
        this.log(`Fetching ${locationUrl}...`);
        const response = await (0, fetchWithProxy_1.default)(locationUrl);
        if (!response.ok) {
            this.error(`Failed to fetch: ${response.statusText}`, { exit: 100 });
        }
        const type = response.headers.get('content-type');
        if (url &&
            type !== 'application/zip' &&
            type !== 'application/octet-stream') {
            this.error('The URL provided does not seem to be a JBrowse installation URL');
        }
        if (clean) {
            rimraf_1.default.sync(path_1.default.join(argsPath, 'static'));
            fs_1.default.readdirSync(argsPath)
                .filter(f => f.includes('worker.js'))
                .forEach(f => fs_1.default.unlinkSync(path_1.default.join(argsPath, f)));
        }
        await response.body.pipe(unzipper_1.default.Extract({ path: argsPath })).promise();
        this.log(`Unpacked ${locationUrl} at ${argsPath}`);
    }
}
exports.default = Upgrade;
Upgrade.description = 'Upgrades JBrowse 2 to latest version';
Upgrade.examples = [
    '# Upgrades current directory to latest jbrowse release',
    '$ jbrowse upgrade',
    '',
    '# Upgrade jbrowse instance at a specific filesystem path',
    '$ jbrowse upgrade /path/to/jbrowse2/installation',
    '',
    '# Upgrade to a specific tag',
    '$ jbrowse upgrade /path/to/jbrowse2/installation --tag v1.0.0',
    '',
    '# List versions available on github',
    '$ jbrowse upgrade --listVersions',
    '',
    '# Upgrade from a specific URL',
    '$ jbrowse upgrade --url https://sample.com/jbrowse2.zip',
    '',
    '# Get nightly release from main branch',
    '$ jbrowse upgrade --nightly',
];
Upgrade.args = [
    {
        name: 'localPath',
        required: false,
        description: `Location where JBrowse 2 is installed`,
        default: '.',
    },
];
Upgrade.flags = {
    help: command_1.flags.help({ char: 'h' }),
    // will need to account for pagenation once there is a lot of releases
    listVersions: command_1.flags.boolean({
        char: 'l',
        description: 'Lists out all versions of JBrowse 2',
    }),
    tag: command_1.flags.string({
        char: 't',
        description: 'Version of JBrowse 2 to install. Format is v1.0.0.\nDefaults to latest',
    }),
    branch: command_1.flags.string({
        description: 'Download a development build from a named git branch',
    }),
    nightly: command_1.flags.boolean({
        description: 'Download the latest development build from the main branch',
    }),
    clean: command_1.flags.boolean({
        description: 'Removes old js,map,and LICENSE files in the installation',
    }),
    url: command_1.flags.string({
        char: 'u',
        description: 'A direct URL to a JBrowse 2 release',
    }),
};
