// Package: com.lightningkite.ktordb
// Generated by Khrysalis - this file will be overwritten.
import { EntryChange, xEntryChangeMap } from './EntryChange'
import { HasId } from './HasId'
import { Comparable, ReifiedType, listRemoveAll, runOrNull, safeEq, setUpDataClass } from '@lightningkite/khrysalis-runtime'

//! Declares com.lightningkite.ktordb.CollectionChanges
export class CollectionChanges<T extends any> {
    public constructor(public readonly changes: Array<EntryChange<T>> = [], public readonly replace: (Array<T> | null) = null) {
    }
    public static properties = ["changes", "replace"]
    public static propertyTypes(T: ReifiedType) { return {changes: [Array, [EntryChange, T]], replace: [Array, T]} }
    copy: (values: Partial<CollectionChanges<T>>) => this;
    equals: (other: any) => boolean;
    hashCode: () => number;
    
    public static pair<T extends any>(old: (T | null) = null, _new: (T | null) = null) {
        let result = new CollectionChanges<T>(old !== null || _new !== null ? [new EntryChange<T>(old, _new)] : [], undefined);
        
        return result;
    }
}
setUpDataClass(CollectionChanges)

//! Declares com.lightningkite.ktordb.apply>kotlin.collections.Listcom.lightningkite.ktordb.apply.T
export function xListApply<T extends HasId<ID>, ID extends Comparable<ID>>(this_: Array<T>, changes: CollectionChanges<T>): Array<T> {
    if (changes.replace !== null) {
        return changes.replace!;
    }
    const changeable = Array.from(this_);
    for (const change of changes.changes) {
        const old_0 = change.old;
        if (old_0 !== null) {
            listRemoveAll(changeable, (it: T): boolean => (safeEq(it._id, old_0._id)));
        }
        const new_2 = change._new;
        if (new_2 !== null) {
            changeable.push(new_2);
        }
    }
    return changeable;
}

//! Declares com.lightningkite.ktordb.map>com.lightningkite.ktordb.CollectionChangescom.lightningkite.ktordb.map.T
export function xCollectionChangesMap<T extends any, B extends any>(this_: CollectionChanges<T>, mapper: ((a: T) => B)): CollectionChanges<B> {
    return new CollectionChanges<B>(this_.changes.map((it: EntryChange<T>): EntryChange<B> => (xEntryChangeMap<T, B>(it, mapper))), ((): (Array<B> | null) => {
        const temp5 = this_.replace;
        if(temp5 === null) { return null }
        return temp5.map(mapper)
    })());
}