/* tslint:disable */
import { IResolveFileOptions, IResolveContentOptions, ICreateFileOptions, IUpdateContentOptions, ITextSnapshot } from '@files-stack/core';
import { IFileService, FileChangesEvent, FileOperationEvent, IResourceEncodings, IFileStat, IResolveFileResult, IStreamContent, IContent } from '@files-stack/core';
import { URI } from '@vscode/monaco-editor/esm/vs/base/common/uri';
import { Event, Emitter } from '@vscode/monaco-editor/esm/vs/base/common/event';
import * as paths from '@vscode/monaco-editor/esm/vs/base/common/path';
import { timeout } from '@vscode/monaco-editor/esm/vs/base/common/async';

export class TestFileService implements IFileService {

    public _serviceBrand: any;

    public encoding: IResourceEncodings;

    private readonly _onFileChanges: Emitter<FileChangesEvent>;
    private readonly _onAfterOperation: Emitter<FileOperationEvent>;

    private content = 'Hello Html';

    constructor() {
        this._onFileChanges = new Emitter<FileChangesEvent>();
        this._onAfterOperation = new Emitter<FileOperationEvent>();
    }

    public setContent(content: string): void {
        this.content = content;
    }

    public getContent(): string {
        return this.content;
    }

    public get onFileChanges(): Event<FileChangesEvent> {
        return this._onFileChanges.event;
    }

    public fireFileChanges(event: FileChangesEvent): void {
        this._onFileChanges.fire(event);
    }

    public get onAfterOperation(): Event<FileOperationEvent> {
        return this._onAfterOperation.event;
    }

    public fireAfterOperation(event: FileOperationEvent): void {
        this._onAfterOperation.fire(event);
    }

    resolveFile(resource: URI, _options?: IResolveFileOptions): Promise<IFileStat> {
        return Promise.resolve({
            resource,
            etag: Date.now().toString(),
            encoding: 'utf8',
            mtime: Date.now(),
            isDirectory: false,
            name: paths.basename(resource.fsPath)
        });
    }

    resolveFiles(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise<IResolveFileResult[]> {
        return Promise.all(toResolve.map(resourceAndOption => this.resolveFile(resourceAndOption.resource, resourceAndOption.options))).then(stats => stats.map(stat => ({ stat, success: true })));
    }

    existsFile(_resource: URI): Promise<boolean> {
        return Promise.resolve(null);
    }

    resolveContent(resource: URI, _options?: IResolveContentOptions): Promise<IContent> {
        return Promise.resolve({
            resource: resource,
            value: this.content,
            etag: 'index.txt',
            encoding: 'utf8',
            mtime: Date.now(),
            name: paths.basename(resource.fsPath)
        });
    }

    resolveStreamContent(resource: URI, _options?: IResolveContentOptions): Promise<IStreamContent> {
        return Promise.resolve({
            resource: resource,
            value: {
                on: (event: string, callback: Function): void => {
                    if (event === 'data') {
                        callback(this.content);
                    }
                    if (event === 'end') {
                        callback();
                    }
                }
            },
            etag: 'index.txt',
            encoding: 'utf8',
            mtime: Date.now(),
            name: paths.basename(resource.fsPath)
        });
    }

    updateContent(resource: URI | string, _value: string | ITextSnapshot, _options?: IUpdateContentOptions): Promise<IFileStat> {
        const res = URI.parse(resource as string);
        console.log('---uri res', res);
        return {
            resource: res,
            etag: 'index.txt',
            encoding: 'utf8',
            mtime: Date.now(),
            isDirectory: false,
            name: paths.basename(res.fsPath)
        } as any;
    }

    moveFile(_source: URI, _target: URI, _overwrite?: boolean): Promise<IFileStat> {
        return Promise.resolve(null);
    }

    copyFile(_source: URI, _target: URI, _overwrite?: boolean): Promise<IFileStat> {
        return Promise.resolve(null);
    }

    createFile(_resource: URI, _content?: string, _options?: ICreateFileOptions): Promise<IFileStat> {
        return Promise.resolve(null);
    }

    readFolder(_resource: URI) {
        return Promise.resolve([]);
    }

    createFolder(_resource: URI): Promise<IFileStat> {
        return Promise.resolve(null);
    }

    onDidChangeFileSystemProviderRegistrations = Event.None;

    registerProvider(_scheme: string, _provider) {
        return { dispose() { } };
    }

    activateProvider(_scheme: string) {
        return Promise.resolve(null);
    }

    canHandleResource(resource: URI): boolean {
        return resource.scheme === 'file';
    }

    del(_resource: URI, _options?: { useTrash?: boolean, recursive?: boolean }): Promise<void> {
        return Promise.resolve(null);
    }

    watchFileChanges(_resource: URI): void {
    }

    unwatchFileChanges(_resource: URI): void {
    }

    getWriteEncoding(_resource: URI): string {
        return 'utf8';
    }

    dispose(): void {
    }
}