import { Args } from '@oclif/core';
import { Download } from '@trebuchet/sdk-nodejs';
import { SingleBar } from 'cli-progress';
import { DateTime } from 'luxon';
import { stat } from 'node:fs/promises';
import { resolve } from 'node:path';
import { BaseCommand, TRANSFER_PARTIAL_ID } from '../base.js';
export default class DownloadFile extends BaseCommand {
    static args = {
        id: TRANSFER_PARTIAL_ID,
        destination: Args.string({
            default: '.',
            description: 'Destination folder or file output path',
            required: false,
        }),
    };
    static description = `
Downloads a specific file by ID to the given destination path.
  `;
    static enableJsonFlag = true;
    static summary = 'Download a transfer by ID.';
    async run() {
        let file = await this.matchTransfer(this.args.id);
        let bar;
        if (!this.flags.json) {
            bar = new SingleBar({
                clearOnComplete: true,
                format: '[{bar}] {percentage}% | ETA: {eta}s',
            });
        }
        const dl = new Download(this.sdk, file.publicId, (done, total) => {
            if (bar) {
                if (bar.isActive) {
                    bar.update(done);
                }
                else {
                    bar.start(total, done);
                }
            }
        });
        file = await dl.getInfo();
        if (dl.sharedSecret) {
            if (!file.invite) {
                throw new Error('Invite not available');
            }
            const meta = await this.getInvite(file.invite?.publicId);
            await dl.setPrivateKeyJwk(meta.private_key);
        }
        else if (dl.urlFragment) {
            throw new Error('This command currently only supports downloading individual files from a sharing request. Please use the original sharing link for sent transfers.');
        }
        const fileMeta = await dl.getMeta();
        this.log(file.description);
        this.log(`Created:   ${DateTime.fromJSDate(file.created).toLocaleString(DateTime.DATETIME_FULL)}`);
        this.log(`File Name: ${fileMeta.name}`);
        this.log(`Type:      ${fileMeta.type}`);
        this.log(`Size:      ${fileMeta.size} bytes`);
        this.log();
        let dlPath = this.args.destination;
        try {
            const dlStat = await stat(dlPath);
            if (dlStat.isDirectory()) {
                dlPath = resolve(this.args.destination, fileMeta.name);
            }
        }
        catch {
            // ENOENT, probably
        }
        await dl.getContent(dlPath);
        if (bar) {
            bar.stop();
        }
        return file;
    }
}
