/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
'use strict';

import { commands, debug, tests, workspace, CancellationToken, TestController, TestItem, TestRunProfileKind, TestRunRequest, Uri, TestRun, TestMessage, Location, Position, MarkdownString, TestRunProfile, CancellationTokenSource } from "vscode";
import * as path from 'path';
import { asRange, TestCase, TestSuite } from "./protocol";
import { COMMAND_PREFIX, listeners, TEST_PROGRESS_EVENT } from "./extension";

type SuiteState = 'enqueued' | 'started' | 'passed' | 'failed' | 'skipped' | 'errored';

export class NbTestAdapter {

    private readonly testController: TestController;
	private disposables: { dispose(): void }[] = [];
    private currentRun: TestRun | undefined;
    private itemsToRun: Set<TestItem> | undefined;
    private started: boolean = false;
    private suiteStates: Map<TestItem, SuiteState>;
    private parallelRunProfile: TestRunProfile | undefined;

    constructor() {
        this.testController = tests.createTestController('apacheNetBeansController', 'Apache NetBeans');
        const runHandler = (request: TestRunRequest, cancellation: CancellationToken) => this.run(request, cancellation);
        this.testController.createRunProfile('Run Tests', TestRunProfileKind.Run, runHandler);
        this.testController.createRunProfile('Debug Tests', TestRunProfileKind.Debug, runHandler);
        this.disposables.push(this.testController);
        this.load();
        this.suiteStates = new Map();
    }

    public registerRunInParallelProfile(projects: string[]) {
        if (!this.parallelRunProfile) {
            const runHandler = (request: TestRunRequest, cancellation: CancellationToken) => this.run(request, cancellation, true, projects);
            this.parallelRunProfile = this.testController.createRunProfile("Run Tests In Parallel", TestRunProfileKind.Run, runHandler, true);
        } 
        this.testController.items.replace([]);
        this.load();
    }

    public testInParallelProfileExist(): boolean {
        return this.parallelRunProfile ? true : false;
    }

    public runTestsWithParallelProfile(projects?: string[]) {
        if (this.parallelRunProfile) {
            this.run(new TestRunRequest(undefined, undefined, this.parallelRunProfile), new CancellationTokenSource().token, true, projects);
        }
    }

    async load(): Promise<void> {
        for (let workspaceFolder of workspace.workspaceFolders || []) {
            const loadedTests: any = await commands.executeCommand(COMMAND_PREFIX + '.load.workspace.tests', workspaceFolder.uri.toString());
            if (loadedTests) {
                loadedTests.forEach((suite: TestSuite) => {
                    this.updateTests(suite);
                });
            }
        }
    }

    async run(request: TestRunRequest, cancellation: CancellationToken, testInParallel: boolean = false, projects?: string[]): Promise<void> {
        if (!this.currentRun) {
            if (!testInParallel) {
                commands.executeCommand('workbench.debug.action.focusRepl');
            }
            cancellation.onCancellationRequested(() => this.cancel());
            this.currentRun = this.testController.createTestRun(request);
            this.currentRun.token.onCancellationRequested(() => this.cancel());
            this.itemsToRun = new Set();
            this.started = false;
            if (request.include) {
                const include = [...new Map(request.include.map(item => !item.uri && item.parent?.uri ? [item.parent.id, item.parent] : [item.id, item])).values()];
                for (let item of include) {
                    if (item.uri) {
                        this.set(item, 'enqueued');
                        item.parent?.children.forEach(child => {
                            if (child.id?.includes(item.id)) {
                                this.set(child, 'enqueued');
                            }
                        })
                        const idx = item.id.indexOf(':');
                        const isNestedClass = item.id.includes('$');
                        const topLevelClassName = item.id.lastIndexOf('.');
                        let nestedClass: string | undefined;
                        if (isNestedClass && topLevelClassName > 0) {
                            nestedClass = idx < 0 
                                ? item.id.slice(topLevelClassName + 1)
                                : item.id.substring(topLevelClassName + 1, idx);
                            nestedClass = nestedClass.replace('$', '.');
                        }
                        if (!cancellation.isCancellationRequested) {
                            try {
                                await commands.executeCommand(request.profile?.kind === TestRunProfileKind.Debug ? COMMAND_PREFIX + '.debug.single' : COMMAND_PREFIX + '.run.single', item.uri.toString(), idx < 0 ? undefined : item.id.slice(idx + 1), 
                                    undefined /* configuration */, nestedClass);
                            } catch(err) {
                                // test state will be handled in the code below
                                console.log(err);
                            }
                        }
                    }
                }
            } else {
                this.testController.items.forEach(item => this.set(item, 'enqueued'));
                for (let workspaceFolder of workspace.workspaceFolders || []) {
                    if (!cancellation.isCancellationRequested) {
                        try {
                            if (testInParallel) {
                                await commands.executeCommand(COMMAND_PREFIX + '.run.test', workspaceFolder.uri.toString(), undefined, undefined, undefined, true, projects);
                            } else {
                                await commands.executeCommand(request.profile?.kind === TestRunProfileKind.Debug ? COMMAND_PREFIX + '.debug.test': COMMAND_PREFIX + '.run.test', workspaceFolder.uri.toString());
                            }
                        } catch(err) {
                            // test state will be handled in the code below
                            console.log(err);
                        }
                    }
                }
            }
            if (this.started) {
                this.itemsToRun.forEach(item => this.set(item, 'skipped'));
            } 
            // TBD - message
            else {
                this.itemsToRun.forEach(item => this.set(item, 'failed', new TestMessage('Build failure'), false, true));    
            }
            this.itemsToRun = undefined;
            this.currentRun.end();
            this.currentRun = undefined;
        }
    }

    set(item: TestItem, state: SuiteState, message?: TestMessage | readonly TestMessage[], noPassDown? : boolean, dispatchBuildFailEvent?: boolean): void {
        if (this.currentRun) {
            switch (state) {
                case 'enqueued':
                    this.dispatchTestEvent(state, item);
                    this.itemsToRun?.add(item);
                    this.currentRun.enqueued(item);
                    break;
                case 'skipped':
                    this.dispatchTestEvent(state, item);
                case 'started':
                case 'passed':
                    this.itemsToRun?.delete(item);
                    this.currentRun[state](item);
                    break;
                case 'failed':
                case 'errored':
                    if (dispatchBuildFailEvent) {
                        this.dispatchTestEvent(state, item);
                    }
                    this.itemsToRun?.delete(item);
                    this.currentRun[state](item, message || new TestMessage(""));
                    break;
            }
            this.suiteStates.set(item, state);
            if (!noPassDown) {
                item.children.forEach(child => this.set(child, state, message, noPassDown, dispatchBuildFailEvent));
            }
        }
    }
    
    dispatchTestEvent(state: SuiteState, testItem: TestItem): void {
        if (testItem.parent && testItem.children.size > 0) {
            if (testItem.id.includes(":") && testItem.parent.parent) {
                // special case when parameterized test
                const testEvent = this.getParametrizedTestEvent(state, testItem);
                if (!testEvent) return;

                this.dispatchEvent(testEvent);
            } else {
                this.dispatchEvent({
                    name: testItem.id,
                    moduleName: testItem.parent.id,
                    modulePath: testItem.parent.uri?.path,
                    state,
                });
            }
        } else if (testItem.children.size === 0) {
            const testSuite = testItem.parent;
            const parentState = testSuite && this.suiteStates.get(testSuite) ? this.suiteStates.get(testSuite) : state;
            if (testSuite) {
                let moduleName = testSuite.parent?.id;
                let modulePath = testSuite.parent?.uri?.path;
                if (testSuite.id.includes(":") && testSuite.parent?.parent) {
                    // special case when parameterized test
                    moduleName = testSuite.parent.parent.id;
                    modulePath = testSuite.parent.parent.uri?.path;
                }
                const testSuiteEvent: any = {
                    name: testSuite.id,
                    moduleName,
                    modulePath,
                    state: parentState,
                    tests: []
                }
                testSuite?.children.forEach(suite => {
                    if (suite.id === testItem.id) {
                        const idx = suite.id.indexOf(':');
                        if (idx >= 0) {
                            const name = suite.id.slice(idx + 1);
                            testSuiteEvent.tests?.push({
                                id: suite.id,
                                name,
                                state
                            })
                        }
                    }
                })
                this.dispatchEvent(testSuiteEvent);
            }
        }
    }

    getParametrizedTestEvent(state: SuiteState, testItem: TestItem): any {
        if (!testItem.parent || !testItem.parent.parent) {
            return undefined;
        }
        let name = testItem.parent.id;
        const idx = name.indexOf(':');
        return {
            name,
            moduleName: testItem.parent.parent.id,
            modulePath: testItem.parent.parent.uri?.path,
            state,
            tests: [
                {
                    id: name,
                    name: name.slice(idx + 1),
                    state
                }
            ]
        }
    }

    dispatchEvent(event: any): void {
        const testProgressListeners = listeners.get(TEST_PROGRESS_EVENT);
        testProgressListeners?.forEach(listener => {
            commands.executeCommand(listener, event);
        })
    }

    cancel(): void {
        debug.stopDebugging();
    }

    dispose(): void {
		this.cancel();
		for (const disposable of this.disposables) {
			disposable.dispose();
		}
		this.disposables = [];
	}

    testOutput(output: string): void {
        if (this.currentRun && output) {
            this.currentRun.appendOutput(output.replace(/\n/g, '\r\n'));
        }
    }

    testProgress(suite: TestSuite): void {
        const currentModule = this.testController.items.get(this.getModuleItemId(suite.moduleName));
        const currentSuite = currentModule?.children.get(suite.name);

        switch (suite.state) {
            case 'loaded':
                this.updateTests(suite);
                break;
            case 'started':
                this.started = true;
                if (currentSuite) {
                    this.set(currentSuite, 'started');
                }
                break;
            case 'passed':
            case "failed":
            case 'errored':
            case 'skipped':
                if (suite.tests) {
                    this.updateTests(suite, true);
                    if (currentSuite && currentModule) {
                        const suiteMessages: TestMessage[] = [];
                        suite.tests?.forEach(test => {
                            if (this.currentRun) {
                                let currentTest = currentSuite.children.get(test.id);
                                if (!currentTest) {
                                    currentSuite.children.forEach(item => {
                                        if (!currentTest) {
                                            const subName = this.subTestName(item, test);
                                            if (subName) {
                                                currentTest = subName === '()' ? item : item.children.get(test.id);
                                            }
                                        }
                                    });
                                }
                                let message: TestMessage | undefined;
                                if (test.stackTrace) {
                                    message = new TestMessage(this.stacktrace2Message(currentTest?.uri?.toString(), test.stackTrace));
                                    if (currentTest) {
                                        const testUri = currentTest.uri || currentTest.parent?.uri;
                                        if (testUri) {
                                            const fileName = path.basename(testUri.path);
                                            const line = test.stackTrace.map(frame => {
                                                const info = frame.match(/^\s*at[^\(]*\((\S*):(\d*)\)$/);
                                                if (info && info.length >= 3 && info[1] === fileName) {
                                                    return parseInt(info[2]);
                                                }
                                                return null;
                                            }).find(l => l);
                                            const pos = line ? new Position(line - 1, 0) : currentTest.range?.start;
                                            if (pos) {
                                                message.location = new Location(testUri, pos);
                                            }
                                        }
                                    } else {
                                        message.location = new Location(currentSuite.uri!, currentSuite.range!.start);
                                    }
                                }
                                if (currentTest && test.state !== 'loaded') {
                                    this.set(currentTest, test.state, message, true);
                                } else if (test.state !== 'passed' && message) {
                                    suiteMessages.push(message);
                                }
                            }
                        });
                        if (suiteMessages.length > 0) {
                            this.set(currentSuite, 'errored', suiteMessages, true);
                            currentSuite.children.forEach(item => this.set(item, 'skipped'));
                        } else {
                            this.set(currentSuite, suite.state, undefined, true);
                        }
                        this.set(currentModule, this.calculateStateFor(currentModule), undefined, true);
                    }
                }
                break;
        }
    }

    calculateStateFor(testItem: TestItem): 'passed' | 'failed' | 'skipped' | 'errored' {
        let passed: number = 0;
        testItem.children.forEach(item => {
            const state = this.suiteStates.get(item);
            if (state === 'enqueued' || state === 'failed') return state;
            if (state === 'passed') passed++;
        })
        if (passed > 0) return 'passed';
        return 'skipped';
    }

    updateTests(suite: TestSuite, testExecution?: boolean): void {
        const moduleName = this.getModuleItemId(suite.moduleName);
        let currentModule = this.testController.items.get(moduleName);
        if (!currentModule) {
            const parsedName = this.parseModuleName(moduleName);
            currentModule = this.testController.createTestItem(moduleName, this.getNameWithIcon(parsedName, 'module'), this.getModulePath(suite));
            this.testController.items.add(currentModule);
        }

        const suiteChildren: TestItem[] = []
        let currentSuite = currentModule.children.get(suite.name);
        const suiteUri = suite.file ? Uri.parse(suite.file) : undefined;
        if (!currentSuite || suiteUri && currentSuite.uri?.toString() !== suiteUri.toString()) {
            currentSuite = this.testController.createTestItem(suite.name, this.getNameWithIcon(suite.name, 'class'), suiteUri);
            suiteChildren.push(currentSuite);
        }
        currentModule.children.forEach(suite => suiteChildren.push(suite));

        const suiteRange = asRange(suite.range);
        if (!testExecution && suiteRange && suiteRange !== currentSuite.range) {
            currentSuite.range = suiteRange;
        }
        const children: TestItem[] = []
        const parentTests: Map<TestItem, TestItem[]> = new Map();
        suite.tests?.forEach(test => {
            let currentTest = currentSuite?.children.get(test.id);
            const testUri = test.file ? Uri.parse(test.file) : undefined;
            if (currentTest) {
                if (testUri && currentTest.uri?.toString() !== testUri?.toString()) {
                    currentTest = this.testController.createTestItem(test.id, this.getNameWithIcon(test.name, 'method'), testUri);
                    currentSuite?.children.add(currentTest);
                }
                const testRange = asRange(test.range);
                if (!testExecution && testRange && testRange !== currentTest.range) {
                    currentTest.range = testRange;
                }
                children.push(currentTest);
            } else {
                if (testExecution) {
                    const parents: Map<TestItem, string> = new Map();
                    currentSuite?.children.forEach(item => {
                        const subName = this.subTestName(item, test);
                        if (subName && '()' !== subName) {
                            parents.set(item, subName);
                        }
                    });
                    const parent = this.selectParent(parents);
                    if (parent) {
                        let arr = parentTests.get(parent.test);
                        if (!arr) {
                            parentTests.set(parent.test, arr = []);
                            children.push(parent.test);
                        }
                        arr.push(this.testController.createTestItem(test.id, this.getNameWithIcon(parent.label, 'method')));
                    }
                } else {
                    currentTest = this.testController.createTestItem(test.id, this.getNameWithIcon(test.name, 'method'), testUri);
                    currentTest.range = asRange(test.range);
                    children.push(currentTest);
                    currentSuite?.children.add(currentTest);
                }
            }
        });
        if (testExecution) {
            parentTests.forEach((val, key) => {
                const item = this.testController.createTestItem(key.id, key.label, key.uri);
                item.range = key.range;
                item.children.replace(val);
                currentSuite?.children.add(item);
            });
        } else {
            currentSuite.children.replace(children);
            currentModule.children.replace(suiteChildren);
        }
    }

    getModuleItemId(moduleName?: string): string {
        return moduleName?.replace(":", "-") || "";
    }
    
    parseModuleName(moduleName: string): string {
        if (!this.parallelRunProfile) {
            return moduleName.replace(":", "-");
        }
        const index = moduleName.indexOf(":");
        if (index !== -1) {
            return moduleName.slice(index + 1);
        }
        const parts = moduleName.split("-");
        return parts[parts.length - 1];
    }
    
    getModulePath(suite: TestSuite): Uri {
        return Uri.parse(suite.modulePath || "");
    }

    getNameWithIcon(itemName: string, itemType: 'module' | 'class' | 'method'): string  {
        switch (itemType) {
            case 'module':
                return `$(project) ${itemName}`;
            case 'class':
                return `$(symbol-class) ${itemName}`;
            case 'method':
                return `$(symbol-method) ${itemName}`;
            default:
                return itemName;
        }
    }

    getNameWithoutIcon(itemName: string): string {
        return itemName.replace(/^\$\([^)]+\)\s*/, "");
    }

    subTestName(item: TestItem, test: TestCase): string | undefined {
        if (test.id.startsWith(item.id)) {
            let label = test.name;
            const nameWithoutIcon = this.getNameWithoutIcon(item.label);
            if (label.startsWith(nameWithoutIcon)) {
                label = label.slice(nameWithoutIcon.length).trim();
            }
            return label;
        } else {
            const regexp = new RegExp(item.id.replace(/[-[\]{}()*+?.,\\^$|\s]/g, '\\$&').replace(/#\w*/g, '\\S*'));
            if (regexp.test(test.id)) {
                return test.name;
            }
        }
        return undefined;
    }

    selectParent(parents: Map<TestItem, string>): {test: TestItem, label: string} | undefined {
        let ret: {test: TestItem, label: string} | undefined = undefined;
        parents.forEach((label, parentTest) => {
            if (ret) {
                if (parentTest.id.replace(/#\w*/g, '').length > ret.test.id.replace(/#\w*/g, '').length) {
                    ret = {test: parentTest, label};
                }
            } else {
                ret = {test: parentTest, label};
            }
        });
        return ret;
    }

    stacktrace2Message(currentTestUri: string | undefined, stacktrace: string[]): MarkdownString {
        const regExp: RegExp = /(\s*at\s+(?:[\w$\\.]+\/)?((?:[\w$]+\.)+[\w\s$<>]+))\(((.*):(\d+))\)/;
        const message = new MarkdownString();
        message.isTrusted = true;
        message.supportHtml = true;
        for (const line of stacktrace) {
            if (message.value.length) {
                message.appendMarkdown('<br/>');
            }
            const result = regExp.exec(line);
            if (result) {
                message.appendText(result[1]).appendText('(').appendMarkdown(`[${result[3]}](command:${COMMAND_PREFIX}.open.stacktrace?${encodeURIComponent(JSON.stringify([currentTestUri, result[2], result[4], +result[5]]))})`).appendText(')');
            } else {
                message.appendText(line);
            }
        }
        return message;
    }
}
