/* eslint-disable react-hooks/rules-of-hooks */
import _ from 'lodash';
import { convertDocumentWithCalibre, convertDocumentWithLibreOffice, convertDocumentWithPandoc, slicePdf, useConvertDocumentWithCalibre, useConvertDocumentWithLibreOffice, useConvertDocumentWithPandoc, useSplitPdf, } from '../node/document.js';
import { convertFontWithFontForge, useConvertFontWithFontForge, } from '../node/font.js';
import { convertVideoWithFfmpeg, useConvertVideoWithFfmpeg, } from '../node/video.js';
import { convertImageWithImageMagick, useConvertImageWithImageMagick, } from '../node/image.js';
import { convertArchive, useConvertArchive } from '../node/archive.js';
import { build_command_to_convert_document_with_calibre, build_command_to_convert_document_with_libre_office, build_command_to_convert_document_with_pandoc, build_command_to_convert_font_with_font_forge, } from '../shared/type/source/index.js';
import kink from '../shared/kink.js';
export const CONVERT_KEY = {
    i: { line: ['input', 'file', 'path'] },
    o: { line: ['output', 'file', 'path'], need: false },
    a: { line: ['input', 'format'], need: false },
    b: { line: ['output', 'format'], need: false },
    O: { line: ['output', 'directory', 'path'], need: false },
    I: { line: ['input', 'directory', 'path'], need: false },
    h: { line: ['help'], need: false, like: 'boolean' },
};
function transferInput(source, map) {
    const out = {};
    for (const name in source.detail) {
        const link = map[name];
        const detail = source.detail[name]?.map(v => {
            switch (link?.like) {
                case 'string':
                    return v;
                case 'integer':
                    return parseInt(v, 10);
                case 'decimal':
                    return parseFloat(v);
            }
            return v;
        }) ?? [];
        const val = link?.list ? detail : detail[0];
        if (link?.line) {
            _.set(out, link.line, val);
        }
        else if (val != null) {
            out[name] = val;
        }
    }
    return out;
}
export async function call(task, source) {
    switch (task) {
        case 'convert': {
            const base = transferInput(source, CONVERT_KEY);
            if (await useConvertDocumentWithPandoc('convert', base)) {
                const form = build_command_to_convert_document_with_pandoc;
                if (source.help) {
                    return showHelpForConvert(form);
                }
                const input = transferInput(source, buildInputMapping(form));
                return await convertDocumentWithPandoc(input);
            }
            if (await useConvertDocumentWithCalibre('convert', base)) {
                const form = build_command_to_convert_document_with_calibre;
                if (source.help) {
                    return showHelpForConvert(form);
                }
                const input = transferInput(source, buildInputMapping(form));
                return await convertDocumentWithCalibre(input);
            }
            if (await useConvertDocumentWithLibreOffice('convert', base)) {
                const form = build_command_to_convert_document_with_libre_office;
                if (source.help) {
                    return showHelpForConvert(form);
                }
                const input = transferInput(source, buildInputMapping(form));
                return await convertDocumentWithLibreOffice(input);
            }
            if (await useConvertFontWithFontForge('convert', base)) {
                const form = build_command_to_convert_font_with_font_forge;
                if (source.help) {
                    return showHelpForConvert(form);
                }
                const input = transferInput(source, buildInputMapping(form));
                return await convertFontWithFontForge(input);
            }
            if (await useConvertImageWithImageMagick('convert', base)) {
                return await convertImageWithImageMagick(source);
            }
            if (await useConvertVideoWithFfmpeg('convert', base)) {
                return await convertVideoWithFfmpeg(source);
            }
            if (await useConvertArchive('convert', base)) {
                return await convertArchive(source);
            }
            break;
        }
        case 'slice': {
            if (await useSplitPdf('slice', source)) {
                return await slicePdf(source);
            }
            break;
        }
        case 'format': {
            break;
        }
        case 'compress': {
            break;
        }
        case 'decompress': {
            break;
        }
    }
    throw kink('task_not_implemented', {
        task: task,
        link: Object.keys(source.detail),
    });
}
function showHelpForConvert(form) {
    console.log('usage:');
    console.log('');
    console.log(`  task convert -i <input-path> -o <output-path>`);
    console.log('');
    console.log('options:');
    console.log('');
    buildCliOptions(form).forEach(({ link, note }) => {
        console.log(`  ${link.join(', ')}`);
        if (note) {
            console.log(`    ${note}`);
        }
    });
    console.log('');
}
function buildCliOptions(form, line = []) {
    const opts = [];
    if ('link' in form && form.link) {
        for (const name in form.link) {
            const link = form.link[name];
            if (!link) {
                continue;
            }
            const lineName = line.concat([name]);
            if (link.link) {
                opts.push(...buildCliOptions(link, lineName));
            }
            else {
                const mark = link.name?.mark && `-${link.name.mark}`;
                const name = `--${_.kebabCase(lineName.join('-'))}`;
                const list = [mark, name].filter(x => x);
                opts.push({
                    link: list,
                    note: link.note,
                    line: lineName,
                });
            }
        }
    }
    return opts;
}
function buildInputMapping(form) {
    const list = buildCliOptions(form);
    const map = list.reduce((m, x) => {
        x.link.forEach(link => {
            m[link.replace(/^\-+/, '')] = { line: x.line };
        });
        return m;
    }, {});
    return map;
}
//# sourceMappingURL=task.js.map