const vscode = require('vscode');
const topjsDebug = require('./topjsDebug');
const net = require('net');
const path = require('path');

function activate(context) {
    context.subscriptions.push(vscode.commands.registerCommand('extension.topjs-debugger.getProgramPath', config => {
        var p = vscode.window.activeTextEditor.document.fileName;
        return path.basename(p);
    }));
    const provider = new TopJSConfigurationProvider();
    context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('topjs', provider));
    var x = true;
    if(x) {
        const factory = new TopJSDebugAdapterDescriptorFactory();
        context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('topjs', factory));
        context.subscriptions.push(factory);
    }
}

function deactivate() {}

exports.activate = activate;
exports.deactivate = deactivate;

class TopJSConfigurationProvider {
    resolveDebugConfigguration(folder, config, token) {
        if(!config.type && !config.request && !config.name) {
            const editor = vscode.window.activeTextEditor;
            if(editor && editor.document.languageId == 'javascript') {
                config.type = 'topjs';
                config.name = 'Launch Debug';
                config.request = 'launch';
                config.program = '${file}';
                config.stopOnEntry = true;
            }
        }
        if(!config.program) {
            return vscode.window.showInformationMessage("Cannot find a program to debug").then(_ => {
                return undefined;
            });
        }
        return config;
    }
}

class TopJSDebugAdapterDescriptorFactory {
    createDebugAdapterDescriptor(session, executable) {
        if(!this.server) {
            this.server = net.createServer(socket => {
                const session = new topjsDebug.TopJSDebugSession();
                session.setRunAsServer(true);
                session.start(socket, socket);
            }).listen(0); // listen on random port
        }
        return new vscode.DebugAdapterServer(this.server.address().port);
    }

    dispose() {
        if(this.server) {
            this.server.close();
        }
    }
}