'use strict';

/**
 * Contract: schema template
 *
 * Browse, preview, dan generate template schema dari koleksi RestForge Schema
 * Reference (85 template, 30 domain, 33 section). Verb ini bertindak sebagai
 * wrapper terhadap binary native `sdf-tools.exe` yang di-ship melalui folder
 * bin/. Semua filter dan display flag diteruskan ke binary; help text di sisi
 * Node mempertahankan kontrak CLI (contract validator + help generator).
 *
 * Binary lookup: <package-root>/bin/sdf-tools.exe relatif terhadap file ini
 * (resolusi sama untuk source workspace dan installation di node_modules).
 *
 * Platform: saat ini hanya Windows (sdf-tools.exe). Pemanggilan di non-Windows
 * akan return error eksplisit, bukan crash diam-diam.
 */

const fs = require('fs');
const os = require('os');
const path = require('path');
const { spawnSync } = require('child_process');

const VALUE_FLAGS = ['domain', 'table', 'category', 'pattern', 'section', 'lang', 'path', 'format'];
const BOOLEAN_FLAGS = [
    'has-sdf',
    'no-sdf',
    'show',
    'example',
    'generate',
    'force',
    'list-domains',
    'list-categories',
    'list-sections',
    'stats'
];

function resolveBinaryPath() {
    if (os.platform() !== 'win32') return null;
    return path.resolve(__dirname, '..', '..', '..', 'bin', 'sdf-tools.exe');
}

function buildBinaryArgs(args) {
    const out = [];
    for (const name of VALUE_FLAGS) {
        const value = args[name];
        if (value === undefined || value === null || value === '') continue;
        out.push(`--${name}=${value}`);
    }
    for (const name of BOOLEAN_FLAGS) {
        if (args[name] === true) {
            out.push(`--${name}`);
        }
    }
    return out;
}

module.exports = {
    resource: 'schema',
    verb: 'template',
    description: 'Browse, preview, dan generate template schema dari koleksi RestForge Schema Reference',
    category: 'utility',
    flags: {
        domain: {
            type: 'string',
            required: false,
            default: null,
            description: 'Filter berdasarkan domain (csv, mis. erp atau erp,finance)'
        },
        table: {
            type: 'string',
            required: false,
            default: null,
            description: 'Filter nama tabel (wildcard glob: sales*, *_invoice)'
        },
        category: {
            type: 'string',
            required: false,
            default: null,
            description: 'Filter category: master-data atau transactional'
        },
        pattern: {
            type: 'string',
            required: false,
            default: null,
            description: 'Filter pattern: single-table atau master-detail'
        },
        section: {
            type: 'string',
            required: false,
            default: null,
            description: 'Filter section code (lihat --list-sections)'
        },
        'has-sdf': {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Filter hanya template yang sudah punya versi SDF'
        },
        'no-sdf': {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Filter hanya template yang belum punya SDF (gap analysis)'
        },
        show: {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Cetak schema template (perlu --table=<nama_spesifik>)'
        },
        example: {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Sertakan section CONTOH DATA (kombinasi dengan --show)'
        },
        lang: {
            type: 'string',
            required: false,
            default: null,
            description: 'Format schema: sdf (default) atau sql'
        },
        generate: {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Generate template ke filesystem (perlu --table dan --path)'
        },
        path: {
            type: 'string',
            required: false,
            default: null,
            description: 'Path destination untuk --generate (direktori atau file)'
        },
        force: {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Overwrite file destination existing saat --generate'
        },
        'list-domains': {
            type: 'boolean',
            required: false,
            default: false,
            description: 'List semua domain aplikasi yang tersedia'
        },
        'list-categories': {
            type: 'boolean',
            required: false,
            default: false,
            description: 'List semua category template'
        },
        'list-sections': {
            type: 'boolean',
            required: false,
            default: false,
            description: 'List semua section beserta category-nya'
        },
        stats: {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Tampilkan statistik koleksi (per category, pattern, domain, section)'
        },
        format: {
            type: 'string',
            required: false,
            default: null,
            description: 'Format output: table (default), plain, atau json'
        }
    },
    examples: [
        'npx restforge schema template',
        'npx restforge schema template --domain=erp',
        'npx restforge schema template --domain=erp,inventory --category=master-data',
        'npx restforge schema template --table=sales_order --show',
        'npx restforge schema template --table=sales_order --show --lang=sql',
        'npx restforge schema template --table=sales_order --generate --path=./schema --lang=sdf',
        'npx restforge schema template --stats',
        'npx restforge schema template --list-domains'
    ],
    async handler(args) {
        const binaryPath = resolveBinaryPath();
        if (!binaryPath) {
            const err = new Error(
                `schema template hanya tersedia di Windows (sdf-tools.exe). Platform saat ini: ${os.platform()}`
            );
            err.exitCode = 3;
            throw err;
        }

        if (!fs.existsSync(binaryPath)) {
            const err = new Error(
                `sdf-tools.exe tidak ditemukan di ${binaryPath}. ` +
                'Pastikan binary sudah di-build dan tersedia di folder bin/ package.'
            );
            err.exitCode = 3;
            throw err;
        }

        const binaryArgs = buildBinaryArgs(args);
        const result = spawnSync(binaryPath, binaryArgs, {
            stdio: 'inherit',
            windowsHide: true
        });

        if (result.error) {
            const err = new Error(`Gagal menjalankan sdf-tools.exe: ${result.error.message}`);
            err.exitCode = 1;
            throw err;
        }

        const status = typeof result.status === 'number' ? result.status : 1;
        if (status !== 0) {
            const err = new Error(`sdf-tools.exe exit code ${status}`);
            err.exitCode = status;
            err.silent = true;
            throw err;
        }
    }
};
