import { getTimestampInTicks, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
import { UUID_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';
import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
import { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';
import { APP_NAME_REGEXP, APP_REL8N_NAME, } from './app-constants.mjs';
import { WitnessFormBuilder } from '../witness-form-builder.mjs';
import { persistTransformResult, registerNewIbGib, rel8ToSpecialIbGib } from '../space/space-helper.mjs';
const logalot = GLOBAL_LOG_A_LOT || false;
export function getAppResultMetadata({ app }) {
    return `${app.ib} ${getTimestampInTicks()}`;
}
export function validateCommonAppData({ appData, }) {
    const lc = `[${validateCommonAppData.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting...`);
        }
        if (!appData) {
            throw new Error(`appData required (E: 3df782b29bc4406a87e4895cfcea28ed)`);
        }
        const errors = [];
        const { name, uuid, classname, } = appData;
        if (name) {
            if (!name.match(APP_NAME_REGEXP)) {
                errors.push(`name must match regexp: ${APP_NAME_REGEXP}`);
            }
        }
        else {
            errors.push(`name required.`);
        }
        if (uuid) {
            if (!uuid.match(UUID_REGEXP)) {
                errors.push(`uuid must match regexp: ${UUID_REGEXP}`);
            }
        }
        else {
            errors.push(`uuid required.`);
        }
        if (classname) {
            if (!classname.match(APP_NAME_REGEXP)) {
                errors.push(`classname must match regexp: ${APP_NAME_REGEXP}`);
            }
        }
        return errors;
    }
    catch (error) {
        console.error(`${lc} ${error.message}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
export function getAppIb({ appData, classname, }) {
    const lc = `[${getAppIb.name}]`;
    try {
        const validationErrors = validateCommonAppData({ appData });
        if (validationErrors.length > 0) {
            throw new Error(`invalid appData: ${validationErrors} (E: 9aff04f0cfc54a5188ca8bc40764160d)`);
        }
        if (classname) {
            if (appData.classname && appData.classname !== classname) {
                throw new Error(`classname does not match appData.classname (E: 66f1447eef97485fba521c40980f5eb5)`);
            }
        }
        else {
            classname = appData.classname;
            if (!classname) {
                throw new Error(`classname required (E: 5f6ffb4317044125b94f662070e1f40b)`);
            }
        }
        const { name, uuid } = appData;
        return `app ${classname} ${name} ${uuid}`;
    }
    catch (error) {
        console.error(`${lc} ${error.message}`);
        throw error;
    }
}
/**
 * Current schema is `app ${classname} ${name} ${uuid}`
 *
 * NOTE this is space-delimited
 */
export function getInfoFromAppIb({ appIb, }) {
    const lc = `[${getInfoFromAppIb.name}]`;
    try {
        if (!appIb) {
            throw new Error(`appIb required (E: 6b065aee67e641ba9f9c6db367ebb0fb)`);
        }
        const pieces = appIb.split(' ');
        return {
            appClassname: pieces[1],
            appName: pieces[2],
            appId: pieces[3],
        };
    }
    catch (error) {
        console.error(`${lc} ${error.message}`);
        throw error;
    }
}
export function getAppInfoIb({ appData, appTjpGib, classname, }) {
    const lc = `[${getAppIb.name}]`;
    try {
        const validationErrors = validateCommonAppData({ appData });
        if (validationErrors.length > 0) {
            throw new Error(`invalid appData: ${validationErrors} (E: 7be1f54ce8af4e4982966b2dedb4cf6e)`);
        }
        if (classname) {
            if (appData.classname && appData.classname !== classname) {
                throw new Error(`classname does not match appData.classname (E: 64bd9eaef1f94be8856e18b791d4ae52)`);
            }
        }
        else {
            classname = appData.classname;
            if (!classname) {
                throw new Error(`classname required (E: 8d194cf8fb3f4c8eb2f708e0ccfe187c)`);
            }
        }
        const { name, uuid } = appData;
        return `info_app ${classname} ${name} ${uuid} ${appTjpGib ?? 0}`;
    }
    catch (error) {
        console.error(`${lc} ${error.message}`);
        throw error;
    }
}
/**
 * Current schema is `info_app ${classname} ${name} ${uuid} ${appTjpGib ?? 0}`
 *
 * NOTE this is space-delimited
 */
export function getInfoFromAppInfoIb({ appInfoIb, }) {
    const lc = `[${getInfoFromAppIb.name}]`;
    try {
        if (!appInfoIb) {
            throw new Error(`appInfoIb required (E: d12756f218144d22acb14c794dd3eeef)`);
        }
        const pieces = appInfoIb.split(' ');
        if (pieces.length !== 5) {
            throw new Error(`invalid appInfoIb. Expected space-delimited pieces.length === 5 (E: 21bfc58e4d88c298680ea95bc6dfc622)`);
        }
        return {
            appClassname: pieces[1],
            appName: pieces[2],
            appId: pieces[3],
            appTjpGib: pieces[4],
        };
    }
    catch (error) {
        console.error(`${lc} ${error.message}`);
        throw error;
    }
}
/**
 * Prompts the user a form to build the app.
 *
 * Once prompted, the app is:
 * 1. validated
 * 2. persisted in the given {@link space}
 * 3. registered with the space
 * 4. related to the space's special apps index
 * 5. new app is returned
 *
 * @returns newly created app ibgib (witness)
 */
export async function createNewApp({ fnPromptApp, ibgibs, space, }) {
    const lc = `[${createNewApp.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting...`);
        }
        if (!ibgibs) {
            throw new Error(`ibgibs all powerful service required. (E: b24e78de0d204dc78909022bee296b30)`);
        }
        space = space ?? await ibgibs.getLocalUserSpace({ lock: true });
        // prompt user to create the ibgib, passing in null because we're
        // creating not editing.
        let resApp = await fnPromptApp(space, /*ibGib*/ null);
        if (!resApp) {
            throw new Error(`resApp falsy after prompt for app. (E: 2225a567abcd680a5e957e81fbb64123)`);
        }
        /** this should be the witness class itself at this point. */
        const newApp = resApp.newIbGib;
        let allIbGibs = [];
        allIbGibs.push(newApp);
        resApp.intermediateIbGibs?.forEach((x) => allIbGibs.push(x));
        resApp.dnas?.forEach((x) => allIbGibs.push(x));
        for (let i = 0; i < allIbGibs.length; i++) {
            const ibGib = allIbGibs[i];
            const validationErrors = await validateIbGibIntrinsically({ ibGib });
            if ((validationErrors ?? []).length > 0) {
                throw new Error(`(UNEXPECTED) invalid app ibgib created. validationErrors: ${validationErrors}. app: ${pretty(newApp.toIbGibDto())} (E: 54cfc2f6bc284ed79be91d2da5e4bd2f)`);
            }
        }
        await persistTransformResult({ resTransform: resApp, space });
        const { zeroSpace, fnBroadcast, fnUpdateBootstrap } = ibgibs;
        await registerNewIbGib({
            ibGib: newApp,
            space,
            fnBroadcast: (x) => fnBroadcast(x),
        });
        await rel8ToSpecialIbGib({
            type: "apps",
            rel8nName: APP_REL8N_NAME,
            ibGibsToRel8: [newApp],
            space,
            zeroSpace,
            fnUpdateBootstrap,
            fnBroadcast,
        });
        return newApp;
    }
    catch (error) {
        debugger; // before error
        console.error(`${lc} ${error.message}`);
        return;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
export class AppFormBuilder extends WitnessFormBuilder {
    lc = `[${AppFormBuilder.name}]`;
    constructor() {
        super();
        this.what = 'app';
    }
    icon({ of, required, defaultValue, iconsList, }) {
        // const exampleIonicons = IONICONS.slice(0, 4).map(x => `"${x}"`).join(', ');
        const exampleIonicons = iconsList.slice(0, 4).map(x => `"${x}"`).join(', ');
        this.addItem({
            // witness.data.outputPrefix
            name: "icon",
            description: `Icon name for the app's icon in the app bar. (NOTE: Only ionicons right now, e.g. ${exampleIonicons}). See https://ionic.io/ionicons for a full list.`,
            label: "Icon",
            fnValid: (x) => { return typeof x === 'string' && iconsList.includes(x); },
            defaultErrorMsg: `Must be a valid icon from the icons list.`,
            dataType: 'select',
            value: of,
            defaultValue: defaultValue || 'beer',
            selectOptions: [
                ...iconsList,
            ],
            required,
        });
        return this;
    }
}
// export function documentLocationIsAtWelcomePage(): boolean {
//     return ['welcome', '/welcome', '/welcome/'].includes(document.location.pathname);
// }
//# sourceMappingURL=app-helper.mjs.map