/*---------------------------------------------------------
 * Copyright 2021 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/
import path = require('path');
import {
	CancellationToken,
	EndOfLine,
	Event,
	EventEmitter,
	FileType,
	MarkdownString,
	Position,
	Range,
	TestController,
	TestItem,
	TestItemCollection,
	TestRun,
	TestRunProfile,
	TestRunProfileKind,
	TestRunRequest,
	TestTag,
	TextDocument,
	TextLine,
	Uri,
	WorkspaceFolder
} from 'vscode';
import { FileSystem, Workspace } from '../../src/goTest/utils';

type TestRunHandler = (request: TestRunRequest, token: CancellationToken) => Thenable<void> | void;

class MockTestCollection implements TestItemCollection {
	constructor(private item: MockTestItem | MockTestController) {}

	[Symbol.iterator](): Iterator<[id: string, testItem: TestItem], any, undefined> {
		throw new Error('Method not implemented.');
	}

	private readonly m = new Map<string, MockTestItem>();

	get size() {
		return this.m.size;
	}

	forEach(fn: (item: TestItem, coll: TestItemCollection) => unknown) {
		for (const item of this.m.values()) fn(item, this);
	}

	add(item: TestItem): void {
		if (this.m.has(item.id)) {
			throw new Error(`Test item ${item.id} already exists`);
		}

		if (!(item instanceof MockTestItem)) {
			throw new Error('not a mock');
		} else if (this.item instanceof MockTestItem) {
			item.parent = this.item;
		}

		this.m.set(item.id, item);
	}

	delete(id: string): void {
		this.m.delete(id);
	}

	get(id: string): TestItem | undefined {
		return this.m.get(id);
	}

	replace(): void {
		throw new Error('not impelemented');
	}
}

class MockTestItem implements TestItem {
	private static idNum = 0;
	private idNum: number;

	constructor(
		public id: string,
		public label: string,
		public uri: Uri | undefined,
		public ctrl: MockTestController
	) {
		this.idNum = MockTestItem.idNum;
		MockTestItem.idNum++;
	}
	tags: readonly TestTag[] = [];
	sortText?: string | undefined;

	parent: TestItem | undefined;
	canResolveChildren = false;
	busy = false;
	description?: string;
	range: Range | undefined;
	error: string | MarkdownString | undefined;
	runnable = false;
	debuggable = false;

	children: MockTestCollection = new MockTestCollection(this);

	invalidateResults(): void {}

	dispose(): void {
		if (this.parent instanceof MockTestItem) {
			this.parent.children.delete(this.id);
		}
	}
}

class MockTestRunProfile implements TestRunProfile {
	constructor(
		public label: string,
		public kind: TestRunProfileKind,
		public runHandler: TestRunHandler,
		public isDefault: boolean
	) {
		const emitter = new EventEmitter<boolean>();
		this.onDidChangeDefault = emitter.event;
	}
	tag: TestTag | undefined;
	onDidChangeDefault: Event<boolean>;
	supportsContinuousRun = false;
	configureHandler(): void {}
	dispose(): void {}
}

class MockTestRun implements TestRun {
	name = 'test run';
	isPersisted = false;

	get token(): CancellationToken {
		throw new Error('Method not implemented.');
	}

	constructor() {
		const emitter = new EventEmitter<void>();
		this.onDidDispose = emitter.event;
	}

	addCoverage(): void {}
	onDidDispose: Event<void>;
	enqueued(): void {}
	started(): void {}
	skipped(): void {}
	failed(): void {}
	errored(): void {}
	passed(): void {}
	appendOutput(): void {}
	end(): void {}
}

export class MockTestController implements TestController {
	id = 'go';
	label = 'Go';
	items = new MockTestCollection(this);

	resolveHandler?: (item: TestItem | undefined) => void | Thenable<void>;
	refreshHandler: ((token: CancellationToken) => void | Thenable<void>) | undefined;

	createTestRun(): TestRun {
		return new MockTestRun();
	}

	createRunProfile(
		label: string,
		kind: TestRunProfileKind,
		runHandler: TestRunHandler,
		isDefault = false
	): TestRunProfile {
		return new MockTestRunProfile(label, kind, runHandler, isDefault);
	}

	createTestItem(id: string, label: string, uri?: Uri): TestItem {
		return new MockTestItem(id, label, uri, this);
	}

	invalidateTestResults(): void {}
	dispose(): void {}
}

type DirEntry = [string, FileType];

class MockTestFileSystem implements FileSystem {
	constructor(
		public dirs: Map<string, DirEntry[]>,
		public files: Map<string, MockTestDocument>
	) {}

	readDirectory(uri: Uri): Thenable<[string, FileType][]> {
		const k = uri.with({ query: '', fragment: '' }).toString();
		return Promise.resolve(this.dirs.get(k) || []);
	}

	readFile(uri: Uri): Thenable<Uint8Array> {
		const k = uri.with({ query: '', fragment: '' }).toString();
		const s = this.files.get(k)?.getText();
		return Promise.resolve(Buffer.from(s || ''));
	}
}

function unindent(s: string): string {
	let lines = s.split('\n');
	if (/^\s*$/.test(lines[0])) lines = lines.slice(1);

	const m = lines[0].match(/^\s+/);
	if (!m) return s;
	if (!lines.every((l) => /^\s*$/.test(l) || l.startsWith(m[0]))) return s;

	for (const i in lines) {
		lines[i] = lines[i].substring(m[0].length);
	}
	return lines.join('\n');
}

export class MockTestWorkspace implements Workspace {
	static from(folders: string[], contents: Record<string, string | { contents: string; language: string }>) {
		const wsdirs: WorkspaceFolder[] = [];
		const dirs = new Map<string, DirEntry[]>();
		const files = new Map<string, MockTestDocument>();

		for (const i in folders) {
			const uri = Uri.parse(folders[i]);
			wsdirs.push({ uri, index: Number(i), name: path.basename(uri.path) });
		}

		function push(uri: Uri, child: FileType) {
			const entry: DirEntry = [path.basename(uri.path), child];
			const dir = uri.with({ path: path.dirname(uri.path) });
			if (dirs.has(dir.toString())) {
				dirs.get(dir.toString())?.push(entry);
				return;
			}

			if (path.dirname(dir.path) !== dir.path) {
				push(dir, FileType.Directory);
			}
			dirs.set(dir.toString(), [entry]);
		}

		for (const k in contents) {
			const uri = Uri.parse(k);
			const entry = contents[k];

			let doc: MockTestDocument;
			if (typeof entry === 'object') {
				doc = new MockTestDocument(uri, unindent(entry.contents), entry.language);
			} else if (path.basename(uri.path) === 'go.mod') {
				doc = new MockTestDocument(uri, unindent(entry), 'go.mod');
			} else {
				doc = new MockTestDocument(uri, unindent(entry));
			}

			files.set(uri.toString(), doc);
			push(uri, FileType.File);
		}

		return new this(wsdirs, new MockTestFileSystem(dirs, files));
	}

	constructor(
		public workspaceFolders: WorkspaceFolder[],
		public fs: MockTestFileSystem
	) {}

	openTextDocument(uri: Uri): Thenable<TextDocument> {
		const doc = this.fs.files.get(uri.toString());
		if (!doc) throw Error('doc not found');
		return Promise.resolve(doc);
	}

	getWorkspaceFolder(uri: Uri): WorkspaceFolder {
		return this.workspaceFolders.filter((x) => x.uri === uri)[0];
	}

	textDocuments: TextDocument[] = [];
}

class MockTestDocument implements TextDocument {
	constructor(
		public uri: Uri,
		private _contents: string,
		public languageId: string = 'go',
		public isUntitled: boolean = false,
		public isDirty: boolean = false
	) {}

	set contents(s: string) {
		this._contents = s;
	}

	readonly version: number = 1;
	readonly eol: EndOfLine = EndOfLine.LF;

	get lineCount() {
		return this._contents.split('\n').length;
	}

	get fileName() {
		return path.basename(this.uri.path);
	}

	save(): Thenable<boolean> {
		if (!this.isDirty) {
			return Promise.resolve(false);
		}

		this.isDirty = false;
		return Promise.resolve(true);
	}

	get isClosed(): boolean {
		throw new Error('Method not implemented.');
	}

	lineAt(line: number): TextLine;
	lineAt(position: Position): TextLine;
	lineAt(): TextLine {
		throw new Error('Method not implemented.');
	}

	offsetAt(): number {
		throw new Error('Method not implemented.');
	}

	positionAt(): Position {
		throw new Error('Method not implemented.');
	}

	getText(range?: Range): string {
		if (range) {
			throw new Error('Method not implemented.');
		}
		return this._contents;
	}

	getWordRangeAtPosition(): Range {
		throw new Error('Method not implemented.');
	}

	validateRange(): Range {
		throw new Error('Method not implemented.');
	}

	validatePosition(): Position {
		throw new Error('Method not implemented.');
	}
}
