import type { GenericEmbedded } from "./embedded";
import type { Annotated } from "./annotated";

export const IsPreservesAnnotated = Symbol.for('IsPreservesAnnotated');

export function isAnnotated<T = GenericEmbedded>(x: any): x is Annotated<T>
{
    return !!x?.[IsPreservesAnnotated];
}

export function is(a: any, b: any): boolean {
    if (isAnnotated(a)) a = a.item;
    if (isAnnotated(b)) b = b.item;
    if (Object.is(a, b)) return true;
    if (typeof a !== typeof b) return false;
    if (typeof a === 'object') {
        if (a === null || b === null) return false;
        if ('equals' in a && typeof a.equals === 'function') return a.equals(b, is);
        if (Array.isArray(a) && Array.isArray(b)) {
            const isRecord = 'label' in a;
            if (isRecord !== 'label' in b) return false;
            if (isRecord && !is((a as any).label, (b as any).label)) return false;
            if (a.length !== b.length) return false;
            for (let i = 0; i < a.length; i++) if (!is(a[i], b[i])) return false;
            return true;
        }
    }
    return false;
}
