// NOTE: do not include this in the univesal index.js output.  It conflicts with
// some of the node/browser functions, so it is up to those to re-export the parts
// they need.
import debug from 'debug';
import * as xlsx from 'xlsx';
import { toCsv } from './slim.js';
import saveFile from 'save-file';
import jszip from 'jszip';
const error = debug('@modusjs/convert#file:error');
const warn = debug('@modusjs/convert#file:error');
const info = debug('@modusjs/convert#file:info');
const trace = debug('@modusjs/convert#file:trace');
// Made this a function so the node code can use it when checking for existing file overwrite
export function computeSaveFilename(args) {
    let { modus, filename, outdir, outputtype } = args;
    if (!Array.isArray(modus)) {
        modus = [modus];
    }
    if (modus.length < 1) {
        error('computeSaveFilename: FAIL: there were no modus results');
        return '';
    }
    // If they pass an outdir, and the filename is not an absolute path, assume
    // the filename should be relative to the outdir.
    const haveoutdir = !!outdir;
    outdir = outdir?.trim().replace(/\/$/, '') || '.'; // handle trailing slashes
    if (outputtype !== 'json') {
        // json can have lots of files to save
        filename = filename || `modus_conversion.${outputtype}`;
    }
    else {
        filename = filename || modus[0].output_filename || 'modus_results.json';
    }
    if (!filename.match(/^\//) && haveoutdir)
        filename = `${outdir}/${filename}`;
    return filename;
}
export async function save(args) {
    let { modus, outputtype, outdir, filename, compact } = args;
    if (!Array.isArray(modus)) {
        modus = [modus];
    }
    if (modus.length < 1) {
        error('Save failed, there were no results to save.');
        throw new Error('ERROR: save failed, there were no results to save.');
    }
    filename = computeSaveFilename(args);
    switch (outputtype) {
        case 'csv':
        case 'xlsx':
            // smoosh them all together into one spreadsheet:
            const { wb } = toCsv(modus.map((m) => m.modus));
            xlsx.writeFile(wb, filename, { bookType: outputtype });
            info('Saved ', outputtype, 'to', filename);
            break;
        case 'json':
            if (modus.length === 1) {
                // single JSON file to save
                const str = compact
                    ? JSON.stringify(modus[0].modus)
                    : JSON.stringify(modus[0].modus, null, '  ');
                await saveFile(str, filename);
            }
            else {
                // more than one json, save it as a zip instead:
                trace('Multiple JSON conversions results found, saving as zip instead of individual JSON files.  Map over them and call save one at a time to save each, or use the node-specific file save.');
                return save({ modus, outputtype: 'zip', outdir, compact }); // use the default zip filename in this case, so don't pass one
            }
            break;
        case 'zip':
            const zip = new jszip();
            // TODO: name something other than modus_conversion when gathering json results
            //       downloaded from trellis
            const folder = zip.folder('modus_conversion');
            if (!folder) {
                throw new Error('Failed to create zip folder when building zip file for download.');
            }
            let i = 0;
            for (const mjr of modus) {
                const str = compact
                    ? JSON.stringify(mjr.modus)
                    : JSON.stringify(mjr.modus, null, '  ');
                folder.file(mjr.output_filename || `modus_result${i++ === 0 ? '' : ` (${i - 1})`}.json`, str);
            }
            const arrbuf = await zip.generateAsync({ type: 'arraybuffer' });
            trace('zip array buffer has', arrbuf.byteLength, 'bytes');
            await saveFile(arrbuf, filename);
            info('Saved zipfile successfully to', filename);
            break;
    }
}
//# sourceMappingURL=file.js.map