// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

import 'package:analysis_server/src/watch_manager.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:watcher/watcher.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(WatchManagerTest);
    defineReflectiveTests(WatchNodeTest);
  });
}

/**
 * Tokens that can be used for testing purposes.
 */
class Token {
  /**
   * A name used for debugging.
   */
  final String name;

  /**
   * Initialize a newly created token to have the given name.
   */
  Token(this.name);

  @override
  String toString() => name;
}

/**
 * A listener that captures the state of watch events so that they can be
 * tested.
 */
class WatchListener {
  /**
   * The event that was passed to the listener method.
   */
  WatchEvent event;

  /**
   * The tokens that were passed to the listener method.
   */
  List<Token> tokens;

  /**
   * Clear the state so that we can distinguish between not receiving an event
   * and receiving the wrong event.
   */
  void clear() {
    this.event = null;
    this.tokens = null;
  }

  /**
   * The listener method.
   */
  void handleWatchEvent(WatchEvent event, List<Token> tokens) {
    this.event = event;
    this.tokens = tokens;
  }
}

@reflectiveTest
class WatchManagerTest extends Object with ResourceProviderMixin {
  WatchListener listener;
  WatchManager<Token> manager;

  void setUp() {
    listener = new WatchListener();
    manager =
        new WatchManager<Token>(resourceProvider, listener.handleWatchEvent);
  }

  Future test_addFolder_folderAndSubfolder() async {
    Folder topFolder = getFolder('/a/b');
    Folder childFolder = getFolder('/a/b/c/d');
    Token topToken = new Token('topToken');
    Token childToken = new Token('childToken');
    manager.addFolder(topFolder, topToken);
    manager.addFolder(childFolder, childToken);

    File newFile1 = newFile('/a/b/c/lib.dart');
    await _expectEvent(ChangeType.ADD, newFile1.path, [topToken]);

    File newFile2 = newFile('/a/b/c/d/lib.dart');
    return _expectEvent(ChangeType.ADD, newFile2.path, [topToken, childToken]);
  }

  Future test_addFolder_singleFolder_multipleTokens() {
    Folder folder = getFolder('/a/b');
    Token token1 = new Token('token1');
    Token token2 = new Token('token2');
    manager.addFolder(folder, token1);
    manager.addFolder(folder, token2);

    File addedFile = newFile('/a/b/lib.dart');
    return _expectEvent(ChangeType.ADD, addedFile.path, [token1, token2]);
  }

  Future test_addFolder_singleFolder_singleToken() async {
    Folder folder = getFolder('/a/b');
    Token token = new Token('token');
    manager.addFolder(folder, token);

    Folder addedFolder = newFolder('/a/b/c');
    await _expectEvent(ChangeType.ADD, addedFolder.path, [token]);

    File addedFile = newFile('/a/b/c/lib.dart');
    return _expectEvent(ChangeType.ADD, addedFile.path, [token]);
  }

  Future test_addFolder_unrelatedFolders() async {
    Folder folder1 = getFolder('/a/b');
    Folder folder2 = getFolder('/c/d');
    Token token1 = new Token('token1');
    Token token2 = new Token('token2');
    manager.addFolder(folder1, token1);
    manager.addFolder(folder2, token2);

    File newFile1 = newFile('/a/b/lib.dart');
    await _expectEvent(ChangeType.ADD, newFile1.path, [token1]);

    File newFile2 = newFile('/c/d/lib.dart');
    return _expectEvent(ChangeType.ADD, newFile2.path, [token2]);
  }

  void test_creation() {
    expect(manager, isNotNull);
  }

  Future test_removeFolder_multipleTokens() {
    Folder folder = getFolder('/a/b');
    Token token1 = new Token('token1');
    Token token2 = new Token('token2');
    manager.addFolder(folder, token1);
    manager.addFolder(folder, token2);
    manager.removeFolder(folder, token2);

    File addedFile = newFile('/a/b/lib.dart');
    return _expectEvent(ChangeType.ADD, addedFile.path, [token1]);
  }

  Future test_removeFolder_withChildren() async {
    Folder topFolder = getFolder('/a/b');
    Folder childFolder = getFolder('/a/b/c/d');
    Token topToken = new Token('topToken');
    Token childToken = new Token('childToken');
    manager.addFolder(topFolder, topToken);
    manager.addFolder(childFolder, childToken);
    manager.removeFolder(topFolder, topToken);

    File addedFile = newFile('/a/b/c/d/lib.dart');
    await _expectEvent(ChangeType.ADD, addedFile.path, [childToken]);

    newFile('/a/b/lib.dart');
    return _expectNoEvent();
  }

  Future test_removeFolder_withNoChildren() {
    Folder folder = getFolder('/a/b');
    Token token = new Token('token');
    manager.addFolder(folder, token);
    manager.removeFolder(folder, token);

    newFile('/a/b/lib.dart');
    return _expectNoEvent();
  }

  Future _expectEvent(ChangeType expectedType, String expectedPath,
      List<Token> expectedTokens) async {
    await pumpEventQueue();
    WatchEvent event = listener.event;
    expect(event, isNotNull);
    expect(event.type, expectedType);
    expect(event.path, expectedPath);
    expect(listener.tokens, unorderedEquals(expectedTokens));
    listener.clear();
  }

  Future _expectNoEvent() async {
    await pumpEventQueue();
    expect(listener.event, isNull);
    expect(listener.tokens, isNull);
  }
}

@reflectiveTest
class WatchNodeTest extends Object with ResourceProviderMixin {
  void test_creation_folder() {
    Folder folder = getFolder('/a/b');
    WatchNode node = new WatchNode(folder);
    expect(node, isNotNull);
    expect(node.children, isEmpty);
    expect(node.folder, folder);
    expect(node.parent, isNull);
    expect(node.subscription, isNull);
    expect(node.tokens, isEmpty);
  }

  void test_creation_noFolder() {
    WatchNode node = new WatchNode(null);
    expect(node, isNotNull);
    expect(node.children, isEmpty);
    expect(node.folder, isNull);
    expect(node.parent, isNull);
    expect(node.subscription, isNull);
    expect(node.tokens, isEmpty);
  }

  void test_delete_nested_child() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
    WatchNode grandchildNode = new WatchNode(getFolder('/a/b/c/d/e'));
    rootNode.insert(topNode);
    rootNode.insert(childNode);
    rootNode.insert(grandchildNode);

    childNode.delete();
    expect(rootNode.children, equals([topNode]));
    expect(topNode.children, equals([grandchildNode]));
    expect(topNode.parent, rootNode);
    expect(grandchildNode.parent, topNode);
  }

  void test_delete_nested_noChild() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
    rootNode.insert(topNode);
    rootNode.insert(childNode);

    childNode.delete();
    expect(rootNode.children, equals([topNode]));
    expect(topNode.children, isEmpty);
    expect(topNode.parent, rootNode);
  }

  void test_delete_top_child() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
    rootNode.insert(topNode);
    rootNode.insert(childNode);

    topNode.delete();
    expect(rootNode.children, equals([childNode]));
    expect(childNode.parent, rootNode);
  }

  void test_delete_top_noChild() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    rootNode.insert(topNode);

    topNode.delete();
    expect(rootNode.children, isEmpty);
  }

  void test_findParent_childOfLeaf() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    rootNode.insert(topNode);

    expect(rootNode.findParent('/a/b/c'), topNode);
  }

  void test_findParent_childOfNonLeaf() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
    rootNode.insert(topNode);
    rootNode.insert(childNode);

    expect(rootNode.findParent('/a/b/c'), topNode);
  }

  void test_findParent_noMatch() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    rootNode.insert(topNode);

    expect(rootNode.findParent('/c/d'), rootNode);
  }

  void test_insert_intermediate_afterParentAndChild() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
    WatchNode intermediateNode = new WatchNode(getFolder('/a/b/c'));

    rootNode.insert(topNode);
    rootNode.insert(childNode);
    rootNode.insert(intermediateNode);
    expect(topNode.parent, rootNode);
    expect(topNode.children, equals([intermediateNode]));
    expect(intermediateNode.parent, topNode);
    expect(intermediateNode.children, equals([childNode]));
    expect(childNode.parent, intermediateNode);
    expect(childNode.children, isEmpty);
  }

  void test_insert_nested_afterParent() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));

    rootNode.insert(topNode);
    rootNode.insert(childNode);
    expect(childNode.parent, topNode);
    expect(childNode.children, isEmpty);
    expect(topNode.children, equals([childNode]));
  }

  void test_insert_nested_beforeParent() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));
    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));

    rootNode.insert(childNode);
    rootNode.insert(topNode);
    expect(childNode.parent, topNode);
    expect(childNode.children, isEmpty);
    expect(topNode.children, equals([childNode]));
  }

  void test_insert_top() {
    WatchNode rootNode = new WatchNode(null);
    WatchNode topNode = new WatchNode(getFolder('/a/b'));

    rootNode.insert(topNode);
    expect(rootNode.children, equals([topNode]));
    expect(topNode.parent, rootNode);
    expect(topNode.children, isEmpty);
  }
}
