/*
 * @module subject helper/util/etc. functions
 *
 * this is where you will find helper functions like those that generate
 * and parse ibs for subject.
 */
// import * as pathUtils from 'path';
// import { statSync } from 'node:fs';
// import { readFile, } from 'node:fs/promises';
// import * as readline from 'node:readline/promises';
// import { stdin, stdout } from 'node:process'; // decide if use this or not
import { extractErrorMsg, clone, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
import { UUID_REGEXP, CLASSNAME_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 { IbGibSpaceAny } from '../../../witness/space/space-base-v1.mjs';
// import { MetaspaceService } from '../../../witness/space/metaspace/metaspace-types.mjs';
import { WitnessFormBuilder } from '../../../witness/witness-form-builder.mjs';
// import { IbGibSubjectAny } from './subject-v1.mjs';
import { DEFAULT_SUBJECT_DATA_V1, } from './subject-types.mjs';
import { SUBJECT_ATOM, SUBJECT_NAME_REGEXP, } from './subject-constants.mjs';
import { Subject_V1_Factory } from './subject-v1.mjs';
/**
 * for logging. import this constant from your project.
 */
const logalot = GLOBAL_LOG_A_LOT;
export function validateCommonSubjectData({ data, }) {
    const lc = `[${validateCommonSubjectData.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting...`);
        }
        if (!data) {
            throw new Error(`Subject Data required (E: 207a82725648e2ef234c8bd3fa1a5312)`);
        }
        const errors = [];
        const { name, uuid, classname, } = data;
        if (name) {
            if (!name.match(SUBJECT_NAME_REGEXP)) {
                errors.push(`name must match regexp: ${SUBJECT_NAME_REGEXP} (E: de987eb8fea0b6232f60abf31815095c)`);
            }
        }
        else {
            errors.push(`name required.`);
        }
        if (uuid) {
            if (!uuid.match(UUID_REGEXP)) {
                errors.push(`uuid must match regexp: ${UUID_REGEXP} (E: 1a6dfda91ad51696f7456bc84dfea60e)`);
            }
        }
        else {
            errors.push(`uuid required.`);
        }
        if (classname) {
            if (!classname.match(CLASSNAME_REGEXP)) {
                errors.push(`classname must match regexp: ${CLASSNAME_REGEXP}`);
            }
        }
        return errors;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
export async function validateCommonSubjectIbGib({ ibGib, }) {
    const lc = `[${validateCommonSubjectIbGib.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: cec6bd96c70e61680fd0e6137d846a94)`);
        }
        const intrinsicErrors = await validateIbGibIntrinsically({ ibGib }) ?? [];
        if (!ibGib.data) {
            throw new Error(`ibGib.data required (E: 50b1815be5abb247f6774048bbaee538)`);
        }
        const ibErrors = [];
        let { SubjectClassname, SubjectName, SubjectId } = parseSubjectIb({ ib: ibGib.ib });
        if (!SubjectClassname) {
            ibErrors.push(`SubjectClassname required (E: bafa26247959d4fd9e41dbed8b839cf5)`);
        }
        if (!SubjectName) {
            ibErrors.push(`SubjectName required (E: d95f7740415c727797c1e26f4888cbe0)`);
        }
        if (!SubjectId) {
            ibErrors.push(`SubjectId required (E: f415b151b37fe80b99b403a1590f2e14)`);
        }
        const dataErrors = validateCommonSubjectData({ data: ibGib.data });
        let result = [...(intrinsicErrors ?? []), ...(ibErrors ?? []), ...(dataErrors ?? [])];
        if (result.length > 0) {
            return result;
        }
        else {
            return undefined;
        }
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
/**
 * builds/rebuilds the ib for Subject based on incoming `data` and `classname`.
 *
 * note that if `data.classname` is truthy, it must match `classname` if also
 * truthy. (`data` is required, but may not necessarily have `classname` in it.)
 *
 * @returns ib based on params
 */
export function getSubjectIb({ data, classname, }) {
    const lc = `[${getSubjectIb.name}]`;
    try {
        const validationErrors = validateCommonSubjectData({ data });
        if (validationErrors.length > 0) {
            throw new Error(`invalid Subject data: ${validationErrors} (E: 55620ac1f17e30a30a92850219f894ac)`);
        }
        if (classname) {
            if (data.classname && data.classname !== classname) {
                throw new Error(`classname does not match data.classname (E: 20e86cca70130839a49ad011c9a7aafa)`);
            }
        }
        else {
            classname = data.classname;
            if (!classname) {
                throw new Error(`classname required (E: 74e29ae0f618fee7e7ef72a30c654a6c)`);
            }
        }
        // ad hoc validation here. should centralize witness classname validation
        const { name, uuid } = data;
        return `witness ${SUBJECT_ATOM} ${classname} ${name} ${uuid}`;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
}
/**
 * Current schema is 'witness [SUBJECT_ATOM] [classname] [SubjectName] [SubjectId]'
 *
 * NOTE this is space-delimited
 */
export function parseSubjectIb({ ib, }) {
    const lc = `[${parseSubjectIb.name}]`;
    try {
        if (!ib) {
            throw new Error(`Subject ib required (E: b29b305c5bc5ba7adf735a037ee4c012)`);
        }
        const pieces = ib.split(' ');
        return {
            SubjectClassname: pieces[2],
            SubjectName: pieces[3],
            SubjectId: pieces[4],
        };
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
}
export class SubjectFormBuilder extends WitnessFormBuilder {
    lc = `[${SubjectFormBuilder.name}]`;
    constructor() {
        super();
        this.what = 'subject';
    }
}
/**
 * helper function to determine if the given `ibGib` is an observer, i.e.,
 * fulfills the {@link Observer} contract.
 *
 * atow (11/2023) the minimal requirement is `ibGib.next` to be a function.
 *
 * @returns true if fulfills the {@link Observer} contract.
 */
export function isObserver({ ibGib, }) {
    const lc = `[${isObserver.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: b54c252104f710c12951aa43b6ead323)`);
        }
        return typeof ibGib.next === 'function';
    }
    catch (error) {
        console.error(`${lc} ${error.message}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
// #region sugar
/**
 * Uses {@link Subject_V1_Factory} to new up a blank subject.
 *
 * ## future
 *
 * in the future, will see about adding a space for persisting this subject (and
 * possibly published events).
 *
 * @returns subject
 */
export async function newupSubject({ data, replay, } = {}) {
    const subjectFactory = new Subject_V1_Factory();
    // starting data
    data ??= clone(DEFAULT_SUBJECT_DATA_V1);
    // additional options
    if (replay) {
        data.replay = true;
    }
    // create it
    const resTransform = await subjectFactory.newUp({ data });
    // return it
    return resTransform.newIbGib;
}
// #endregion sugar
//# sourceMappingURL=subject-helper.mjs.map