import {BehaviorSubject, IBehaviorSubject, MappedBehaviorSubject} from '../BehaviorSubject'

export type DataSource = {
    getField(fieldPath: string): IBehaviorSubject<unknown>
    getAll(): IBehaviorSubject<Record<string, unknown>>
}

export class RecordDataSource implements DataSource {
    private base: BehaviorSubject<Record<string, unknown>> = new BehaviorSubject({})

    getField(field: string): IBehaviorSubject<unknown> {
        return new MappedBehaviorSubject<Record<string, unknown>, typeof field>(this.base, field)
    }

    getAll(): IBehaviorSubject<Record<string, unknown>> {
        return this.base
    }
}

export class DataPlane {
    private sources: Record<string, DataSource> = {}

    public ensureSource(name: string, source?: DataSource) {
        if ( !this.hasSource(name) ) {
            this.addSource(name, source || new RecordDataSource())
        }
    }

    public addSource(name: string, source: DataSource) {
        this.sources[name] = source
    }

    public hasSource(name: string): boolean {
        return Boolean(this.sources[name])
    }

    public getField(source: string, field: string): IBehaviorSubject<unknown> | undefined {
        return this.sources[source]?.getField?.(field)
    }

    public getAll(source: string): IBehaviorSubject<Record<string, unknown>> | undefined {
        return this.sources[source]?.getAll?.()
    }
}
