// import { ITextModelContentProvider } from '@vscode/monaco-editor/esm/vs/editor/common/services/resolverService';
import { ITextModel } from '@vscode/monaco-editor/esm/vs/editor/common/model';
import { URI } from '@vscode/monaco-editor/esm/vs/base/common/uri';
import { FeatureProviderRegistry } from '@workbench-stack/extension-api';
import { Observable, from } from 'rxjs';
import { map, switchMap, first, catchError } from 'rxjs/operators';
import { combineLatestOrDefault, flattenAndCompact } from '@workbench-stack/extension-api';
import { injectable } from 'inversify';
export interface ITextModelContentProvider {
    /**
     * Given a resource, return the content of the resource as `ITextModel`.
     */
    provideTextContent(resource: URI): Promise<ITextModel | undefined | null> | Observable<ITextModel | undefined | null> | null | undefined;
}



/**
 * A registry of providers for a scheme that provide contents within a TextModel.
 */
@injectable()
export class ResourceModelCollection extends FeatureProviderRegistry<string, ITextModelContentProvider> {

    public providersForTextContent(
        key: string,
    ): Observable<ITextModelContentProvider[]> {
        return this.entries.pipe(
            map(entries => entries
                .filter(value => value.registrationOptions === URI.parse(key).scheme)
                .map(({ provider }) => provider)),
        );
    }

    public resolvedTextModelContent(key: string) {
        const resource = URI.parse(key);
        return this.providersForTextContent(key)
            .pipe(
                switchMap(allProviders =>
                    combineLatestOrDefault<ITextModel>(
                        allProviders.map(provider =>
                            from(provider.provideTextContent(resource)).pipe(
                                catchError(err => {
                                    // if (logErrors) {
                                    //     console.error(err);
                                    // }
                                    return [null];
                                }),
                            ),
                        ),
                    ),
                ),
                map(flattenAndCompact),
            );
    }

    public createReferencedObject(key: string, skipActivateProvider?: boolean): Observable<ITextModel> | any {
        const resource = URI.parse(key);

        // File or remote file provider already known
        // if () {

        // }

        // Virtual documents
        if (this.providers.pipe(map(x => !!x))) {
            // return this.resolvedTextModelContent(key).pipe(map => map);
        }

        // // Either uknown scheme, or not yet registered, try to activate
        // @sri not yet implemented
        // if(!skipActivateProvider) {
        //     return fileservice.activateProvider(resource.scheme).then(() => this.createReferencedObject(key, true))
        // }

        return Promise.reject(new Error('resource is not avaialble'));
    }
}
