"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 fs_1 = __importDefault(require("fs"));
const fetchWithProxy_1 = __importDefault(require("../fetchWithProxy"));
const base_1 = __importDefault(require("../base"));
const decompress_1 = __importDefault(require("decompress"));
const fsPromises = fs_1.default.promises;
class Create extends base_1.default {
    async run() {
        const { args: runArgs, flags: runFlags } = this.parse(Create);
        const { localPath: argsPath } = runArgs;
        this.debug(`Want to install path at: ${argsPath}`);
        const { force, url, listVersions, tag, branch, nightly } = runFlags;
        if (listVersions) {
            const versions = (await this.fetchGithubVersions()).map(version => version.tag_name);
            this.log(`All JBrowse versions:\n${versions.join('\n')}`);
            this.exit();
        }
        // mkdir will do nothing if dir exists
        await fsPromises.mkdir(argsPath, { recursive: true });
        if (!force) {
            await this.checkPath(argsPath);
        }
        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');
        }
        await (0, decompress_1.default)(Buffer.from(await response.arrayBuffer()), argsPath);
        this.log(`Unpacked ${locationUrl} at ${argsPath}`);
    }
    async checkPath(userPath) {
        const allFiles = await fsPromises.readdir(userPath);
        if (allFiles.length > 0) {
            this.error(`${userPath} This directory has existing files and could cause conflicts with create. Please choose another directory or use the force flag to overwrite existing files`, { exit: 120 });
        }
    }
    async catch(error) {
        var _a;
        // @ts-expect-error
        if ((_a = error.parse) === null || _a === void 0 ? void 0 : _a.output.flags.listVersions) {
            const versions = (await this.fetchGithubVersions()).map(version => version.tag_name);
            this.log(`All JBrowse versions:\n${versions.join('\n')}`);
            this.exit();
        }
        throw error;
    }
}
Create.description = 'Downloads and installs the latest JBrowse 2 release';
Create.examples = [
    '# Download latest release from github, and put in specific path',
    '$ jbrowse create /path/to/new/installation',
    '',
    '# Download latest release from github and force overwrite existing contents at path',
    '$ jbrowse create /path/to/new/installation --force',
    '',
    '# Download latest release from a specific URL',
    '$ jbrowse create /path/to/new/installation --url url.com/directjbrowselink.zip',
    '',
    '# Download a specific tag from github',
    '$ jbrowse create /path/to/new/installation --tag v1.0.0',
    '',
    '# List available versions',
    '$ jbrowse create --listVersions',
];
Create.args = [
    {
        name: 'localPath',
        required: true,
        description: `Location where JBrowse 2 will be installed`,
    },
];
Create.flags = {
    help: command_1.flags.help({ char: 'h' }),
    force: command_1.flags.boolean({
        char: 'f',
        description: 'Overwrites existing JBrowse 2 installation if present in path',
    }),
    // 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',
    }),
    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',
    }),
    url: command_1.flags.string({
        char: 'u',
        description: 'A direct URL to a JBrowse 2 release',
    }),
    tag: command_1.flags.string({
        char: 't',
        description: 'Version of JBrowse 2 to install. Format is v1.0.0.\nDefaults to latest',
    }),
};
exports.default = Create;
