const path = require('path');
const { JarLanguageClient, StsAdapter } = require('pivotal-atom-languageclient-commons');
const { Convert } = require('atom-languageclient');
const PROPERTIES = require('../properties.json');

const BOOT_DATA_MARKER_TYPE = 'BootApp-Hint';
const BOOT_HINT_GUTTER_NAME = 'boot-hint-gutter';

class BootJavaLanguageClient extends JarLanguageClient {

    constructor() {
        //noinspection JSAnnotator
        super(
            PROPERTIES.jarUrl,
            path.join(__dirname, '..', 'server'),
            'boot-java-language-server.jar'
        );
        // this.DEBUG = true;
    }

    getGrammarScopes() {
        return ['source.java']
    }

    getLanguageName() {
        return 'boot-java'
    }

    getServerName() {
        return 'Spring Boot'
    }

    activate() {
        require('atom-package-deps')
            .install('boot-java')
            .then(() => console.debug('All dependencies installed, good to go'));
        super.activate();
    }

    getOrInstallLauncher() {
        return Promise.resolve('org.springframework.boot.loader.JarLauncher');
    }

    launchVmArgs(version) {
        return super.getOrInstallLauncher().then(lsJar => {
            const toolsJar = this.findJavaFile('lib', 'tools.jar');
            return this.fileExists(toolsJar).then(toolsJarExists => {
                if (!toolsJarExists) {
                    // Notify the user that tool.jar is not found
                    const notification = atom.notifications.addWarning(`"Boot-Java" Package Functionality Limited`, {
                        dismissable: true,
                        detail: 'No tools.jar found',
                        description: 'JAVA_HOME environment variable points either to JRE or JDK missing "lib/tools.jar" hence Boot Hints are unavailable',
                        buttons: [{
                            text: 'OK',
                            onDidClick: () => {
                                notification.dismiss()
                            },
                        }],
                    });
                }
                return [
                    // '-Xdebug',
                    // '-agentlib:jdwp=transport=dt_socket,server=y,address=7999,suspend=n',
                    '-Dorg.slf4j.simpleLogger.logFile=boot-java.log',
                    '-Dorg.slf4j.simpleLogger.defaultLogLevel=debug',
                    '-cp',
                    `${toolsJarExists ? `${toolsJar}:` : ''}${lsJar}`
                ];
            });
        });
    }

    createStsAdapter() {
        return new BootStsAdapter();
    }

}

class BootStsAdapter extends StsAdapter {

    constructor() {
        super();
    }

    onHighlight(params) {
        this.findEditors(params.doc.uri).forEach(editor => this.markHintsForEditor(editor, params.ranges));
    }

    markHintsForEditor(editor, ranges) {
        editor.findMarkers(BOOT_DATA_MARKER_TYPE).forEach(m => m.destroy());
        if (Array.isArray(ranges)) {
            ranges.forEach(range => this.createHintMarker(editor, range));
        }
        const gutter = editor.gutterWithName(BOOT_HINT_GUTTER_NAME);
        if (gutter) {
            if (!ranges || !ranges.length) {
                gutter.hide();
            } else if (!gutter.isVisible()) {
                gutter.show();
            }
        }
    }

    createHintMarker(editor, range) {
        // Create marker model
        const marker = editor.markBufferRange(Convert.lsRangeToAtomRange(range), BOOT_DATA_MARKER_TYPE);

        // Marker around the text in the editor
        editor.decorateMarker(marker, {
            type: 'highlight',
            class: 'boot-hint'
        });

        // Marker in the diagnostic gutter
        let gutter = editor.gutterWithName(BOOT_HINT_GUTTER_NAME);
        if (!gutter) {
            gutter = editor.addGutter({
                name: BOOT_HINT_GUTTER_NAME,
                visible: false,
            });
        }
        const iconElement = document.createElement('span');
        iconElement.setAttribute('class', 'gutter-boot-hint');
        gutter.decorateMarker(marker, {item: iconElement});
    }
}

module.exports = new BootJavaLanguageClient();

@@ -1283,109 +1283,25 @@
     
-return this.fileExists(toolsJar).then(toolsJarExists =%3E %7B%0A                if (!toolsJarExists) %7B%0A    
+if (!toolsJar) %7B%0A
     
@@ -1358,20 +1358,16 @@
 t found%0A
-    
         
@@ -1492,20 +1492,16 @@
         
-    
 dismissa
@@ -1511,20 +1511,16 @@
 : true,%0A
-    
         
@@ -1581,20 +1581,16 @@
         
-    
 descript
@@ -1733,20 +1733,16 @@
         
-    
 buttons:
@@ -1745,20 +1745,16 @@
 ons: %5B%7B%0A
-    
         
@@ -1805,20 +1805,16 @@
         
-    
 onDidCli
@@ -1821,28 +1821,24 @@
 ck: () =%3E %7B%0A
-    
             
@@ -1876,20 +1876,16 @@
 smiss()%0A
-    
         
@@ -1927,20 +1927,12 @@
     
-    %7D%5D,%0A    
+%7D%5D,%0A
     
@@ -1943,28 +1943,24 @@
         %7D);%0A
-    
             
@@ -1969,28 +1969,24 @@
             
-    
 return %5B%0A   
@@ -1997,23 +1997,16 @@
         
-     //
  '-Xdebu
@@ -2025,23 +2025,16 @@
         
- 
-   // 
 '-agentl
@@ -2103,36 +2103,32 @@
                 
-    
 '-Dorg.slf4j.sim
@@ -2169,36 +2169,32 @@
                 
-  
-  
 '-Dorg.slf4j.sim
@@ -2247,23 +2247,15 @@
     
-    
 '-cp',%0A
-    
     
@@ -2281,14 +2281,8 @@
 sJar
-Exists
  ? %60
@@ -2326,29 +2326,9 @@
     
-    %5D;%0A            %7D)
+%5D
 ;%0A  

Fix JDK 9 server launch