'use babel';

/* @flow */

import { Emitter, CompositeDisposable } from 'atom';
/* flow-include
import type { TextEditor, Disposable } from 'atom'
import type { Tester } from './types'
*/

export default class TesterRegistry {
    /* ::
    emitter: Emitter;
    testers: Set<Tester>;
    locks: Set<Tester>;
    testOnChange: boolean;
    subscriptions: CompositeDisposable;
    */

  constructor() {
    this.emitter = new Emitter();
    this.testers = new Set();
    this.locks = new Set();
    this.subscriptions = new CompositeDisposable();


    this.subscriptions.add(atom.config.observe('tester.testOnChange', (testOnChange) => {
      this.testOnChange = testOnChange;
    }));
  }

  hasTester(tester /* : Tester*/) /* : boolean*/ {
    return this.testers.has(tester);
  }

  addTester(tester /* : Tester*/) {
    console.log('addTester', tester);
    this.testers.add(tester);
  }

  deleteTester(tester /* : Tester*/) {
    console.log('deleteTester', tester);
    this.testers.delete(tester);
  }

  onDidUpdateMessages(callback /* : Function*/) /* : Disposable*/ {
    return this.emitter.on('did-update-messages', callback);
  }
  onDidBeginTesting(callback /* : Function*/) /* : Disposable*/ {
    return this.emitter.on('did-begin-testing', callback);
  }
  onDidFinishTesting(callback /* : Function*/) /* : Disposable*/ {
    return this.emitter.on('did-finish-testing', callback);
  }
  dispose() {
    this.testers.clear();
    this.subscriptions.dispose();
  }
  test(onChange/* : Event*/, editorTester/* : TextEditor*/) {
    console.log('TEST', onChange, editorTester);
    const editor = editorTester.getEditor();

    if (
        (onChange && !atom.config.get('tester.testOnFly')) ||
        !editor.getPath() || editor !== atom.workspace.getActiveTextEditor() ||
        this.locks.has(editorTester)
      ) {
      return Promise.resolve();
    }

    this.locks.add(editorTester);
    const scopes = editor.scopeDescriptorForBufferPosition(editor.getCursorBufferPosition()).scopes;
    scopes.push('*');

    const promises = [];
    this.testers.forEach((tester) => {
      promises.push(new Promise((resolve) => {
        resolve(tester.test(editor));
      }).then((results) => {
        if (results) {
          this.emitter.emit('did-update-messages', { tester, messages: results, editor });
        }
      }));
    });
    return Promise.all(promises).then(() =>
        this.locks.delete(editorTester),
      );
  }
}

@@ -1645,79 +1645,8 @@
 if (
-%0A        (onChange && !atom.config.get('tester.testOnFly')) %7C%7C%0A        
 !edi
@@ -1661,16 +1661,24 @@
 ath() %7C%7C
+%0A       
  editor 
@@ -1761,18 +1761,46 @@
 ter)
+) %7B
 %0A      
-) %7B
+console.log('Nothing todo');
 %0A   
@@ -2357,19 +2357,50 @@
 en(() =%3E
+ %7B
 %0A  
+    console.log('All DONE');%0A
       th
@@ -2432,16 +2432,15 @@
 ter)
-,
+;
 %0A    
-  
+%7D
 );%0A 

add logging