import { Args, Flags, ux } 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, REQUEST_PARTIAL_ID } from '../../base.js';
export default class RequestDownload extends BaseCommand {
    static args = {
        id: REQUEST_PARTIAL_ID,
        destination: Args.string({
            default: '.',
            description: 'Destination folder',
            required: false,
        }),
    };
    static description = `
All uploaded files for the sharing request will be downloaded to the given destination folder.
Files that already exist will be skipped, unless --force is specified. 
  `;
    static enableJsonFlag = true;
    static flags = {
        force: Flags.boolean({
            description: 'Skip confirmation prompt.',
        }),
    };
    static summary = 'Download received files from an existing sharing request.';
    async downloadFile(file, meta) {
        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);
                }
            }
        });
        await dl.getInfo();
        await dl.setPrivateKeyJwk(meta.private_key);
        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();
        const dlPath = resolve(this.args.destination, fileMeta.name);
        try {
            await stat(dlPath);
            this.log(`${ux.colorize('yellow', 'Skipped')} - ${dlPath} already exists`);
            return;
        }
        catch {
            // ENOENT, probably
        }
        if (this.flags.force) {
            await dl.getContent(dlPath);
            if (bar) {
                bar.stop();
            }
        }
    }
    async run() {
        const inv = await this.matchInvite(this.args.id);
        const meta = await this.getInvite(inv.publicId);
        const res = await this.sdk.filesApi.getFiles({ flags: 2, inviteId: inv.id, state: ['write_complete'] });
        for (const file of res) {
            await this.downloadFile(file, meta);
        }
        return res;
    }
}
