// Copyright (c) 2014, 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:collection';

import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';

import 'domain_completion_util.dart';

/// A base class for classes containing completion tests.
class CompletionTestCase extends AbstractCompletionDomainTest {
  static const String CURSOR_MARKER = '!';

  List get suggestedCompletions => suggestions
      .map((CompletionSuggestion suggestion) => suggestion.completion)
      .toList();

  void assertHasCompletion(String completion,
      {ElementKind elementKind, bool isDeprecated}) {
    var expectedOffset = completion.indexOf(CURSOR_MARKER);
    if (expectedOffset >= 0) {
      if (completion.contains(CURSOR_MARKER, expectedOffset + 1)) {
        fail(
            "Invalid completion, contains multiple cursor positions: '$completion'");
      }
      completion = completion.replaceFirst(CURSOR_MARKER, '');
    } else {
      expectedOffset = completion.length;
    }
    CompletionSuggestion matchingSuggestion;
    suggestions.forEach((CompletionSuggestion suggestion) {
      if (suggestion.completion == completion) {
        if (matchingSuggestion == null) {
          matchingSuggestion = suggestion;
        } else {
          // It is OK to have a class and its default constructor suggestions.
          if (matchingSuggestion.element?.kind == ElementKind.CLASS &&
                  suggestion.element?.kind == ElementKind.CONSTRUCTOR ||
              matchingSuggestion.element?.kind == ElementKind.CONSTRUCTOR &&
                  suggestion.element?.kind == ElementKind.CLASS) {
            return;
          }
          fail(
              "Expected exactly one '$completion' but found multiple:\n  $suggestedCompletions");
        }
      }
    });
    if (matchingSuggestion == null) {
      fail("Expected '$completion' but found none:\n  $suggestedCompletions");
    }
    expect(matchingSuggestion.selectionOffset, equals(expectedOffset));
    expect(matchingSuggestion.selectionLength, equals(0));
    if (elementKind != null) {
      expect(matchingSuggestion.element.kind, elementKind);
    }
    if (isDeprecated != null) {
      expect(matchingSuggestion.isDeprecated, isDeprecated);
    }
  }

  void assertHasNoCompletion(String completion) {
    if (suggestions.any((CompletionSuggestion suggestion) =>
        suggestion.completion == completion)) {
      fail(
          "Did not expect completion '$completion' but found:\n  $suggestedCompletions");
    }
  }

  /// Discard any results that do not start with the characters the user has
  /// "already typed".
  void filterResults(String content) {
    var charsAlreadyTyped =
        content.substring(replacementOffset, completionOffset).toLowerCase();
    suggestions = suggestions
        .where((CompletionSuggestion suggestion) =>
            suggestion.completion.toLowerCase().startsWith(charsAlreadyTyped))
        .toList();
  }

  Future runTest(LocationSpec spec, [Map<String, String> extraFiles]) {
    super.setUp();
    return Future(() {
      var content = spec.source;
      newFile(testFile, content: content);
      testCode = content;
      completionOffset = spec.testLocation;
      if (extraFiles != null) {
        extraFiles.forEach((String fileName, String content) {
          newFile(fileName, content: content);
        });
      }
    }).then((_) => getSuggestions()).then((_) {
      filterResults(spec.source);
      for (var result in spec.positiveResults) {
        assertHasCompletion(result);
      }
      for (var result in spec.negativeResults) {
        assertHasNoCompletion(result);
      }
    }).whenComplete(() {
      super.tearDown();
    });
  }
}

/// A specification of the completion results expected at a given location.
class LocationSpec {
  String id;
  int testLocation = -1;
  List<String> positiveResults = <String>[];
  List<String> negativeResults = <String>[];
  String source;

  LocationSpec(this.id);

  /// Parse a set of tests from the given `originalSource`. Return a list of the
  /// specifications that were parsed.
  ///
  /// The source string has test locations embedded in it, which are identified
  /// by '!X' where X is a single character. Each X is matched to positive or
  /// negative results in the array of [validationStrings]. Validation strings
  /// contain the name of a prediction with a two character prefix. The first
  /// character of the prefix corresponds to an X in the [originalSource]. The
  /// second character is either a '+' or a '-' indicating whether the string is
  /// a positive or negative result. If logical not is needed in the source it
  /// can be represented by '!!'.
  ///
  /// The [originalSource] is the source for a test that contains test
  /// locations. The [validationStrings] are the positive and negative
  /// predictions.
  static List<LocationSpec> from(
      String originalSource, List<String> validationStrings) {
    Map<String, LocationSpec> tests = HashMap<String, LocationSpec>();
    var modifiedSource = originalSource;
    var modifiedPosition = 0;
    while (true) {
      var index = modifiedSource.indexOf('!', modifiedPosition);
      if (index < 0) {
        break;
      }
      var n = 1; // only delete one char for double-bangs
      var id = modifiedSource.substring(index + 1, index + 2);
      if (id != '!') {
        n = 2;
        var test = LocationSpec(id);
        tests[id] = test;
        test.testLocation = index;
      } else {
        modifiedPosition = index + 1;
      }
      modifiedSource = modifiedSource.substring(0, index) +
          modifiedSource.substring(index + n);
    }
    if (modifiedSource == originalSource) {
      throw StateError('No tests in source: ' + originalSource);
    }
    for (var result in validationStrings) {
      if (result.length < 3) {
        throw StateError('Invalid location result: ' + result);
      }
      var id = result.substring(0, 1);
      var sign = result.substring(1, 2);
      var value = result.substring(2);
      var test = tests[id];
      if (test == null) {
        throw StateError('Invalid location result id: $id for: $result');
      }
      test.source = modifiedSource;
      if (sign == '+') {
        test.positiveResults.add(value);
      } else if (sign == '-') {
        test.negativeResults.add(value);
      } else {
        var err = 'Invalid location result sign: $sign for: $result';
        throw StateError(err);
      }
    }
    var badPoints = <String>[];
    var badResults = <String>[];
    for (var test in tests.values) {
      if (test.testLocation == -1) {
        badPoints.add(test.id);
      }
      if (test.positiveResults.isEmpty && test.negativeResults.isEmpty) {
        badResults.add(test.id);
      }
    }
    if (!(badPoints.isEmpty && badResults.isEmpty)) {
      var err = StringBuffer();
      if (badPoints.isNotEmpty) {
        err.write('No test location for tests:');
        for (var ch in badPoints) {
          err..write(' ')..write(ch);
        }
        err.write(' ');
      }
      if (badResults.isNotEmpty) {
        err.write('No results for tests:');
        for (var ch in badResults) {
          err..write(' ')..write(ch);
        }
      }
      throw StateError(err.toString());
    }
    return tests.values.toList();
  }
}
