// Copyright (c) 2017, 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 'dart:io';

import 'package:status_file/canonical_status_file.dart';
import 'package:status_file/expectation.dart';
import 'package:status_file/status_file_normalizer.dart';
import 'package:status_file/src/expression.dart';

import 'present_failures.dart';
import '../results/result_json_models.dart';
import '../results/failing_test.dart';
import '../results/status_expectations.dart';
import '../results/status_files.dart';
import '../util.dart';
import '../workflow.dart';

final RegExp toggleSectionRegExp = new RegExp(r"^(\d+)$");

/// This is the main workflow step, where the user is asked what to do with the
/// failure and input comments etc. For every test, [onShow] is called with the
/// remaining tests including the one to work on.
class FixFailingTest extends WorkflowStep<List<FailingTest>> {
  final TestResult _testResult;
  FixWorkingItem _currentWorkingItem;
  List<FailingTest> _remainingTests;

  // These fields are mutated to persist user input.
  String _lastComment;
  Set<_CustomSection> _customSections = new Set<_CustomSection>();
  FixWorkingItem _lastWorkingItem;
  StatusExpectations _statusExpectations;

  FixFailingTest(this._testResult);

  @override
  Future<WorkflowAction> onShow(List<FailingTest> payload) async {
    if (payload.isEmpty) {
      print("Finished updating status files from failing tests.");
      print("Trying to find if any new errors have arised from the fixes.");
      return new NavigateStepWorkflowAction(
          new PresentFailures(), [_testResult]);
    }
    // We have to compute status files on every show, because we modify the
    // status files on every fix.
    _statusExpectations = new StatusExpectations(_testResult);
    await _statusExpectations.loadStatusFiles();

    _remainingTests = payload.sublist(1);
    var failingTest = payload.first;

    if (!failingTest.stillFailing(_statusExpectations)) {
      return new NavigateStepWorkflowAction(this, _remainingTests);
    }

    _currentWorkingItem = new FixWorkingItem(failingTest.result.name,
        failingTest, _statusExpectations, _lastComment, _customSections);
    _currentWorkingItem.init();
    print("");
    print("${_remainingTests.length + 1} tests remaining.");
    askAboutTest();

    return new WaitForInputWorkflowAction();
  }

  @override
  Future<WorkflowAction> input(String input) async {
    bool error = false;
    if (input.isEmpty) {
      await fixFailingTest();
      return new NavigateStepWorkflowAction(this, _remainingTests);
    } else if (input == "a") {
      // Add expression.
      var expression = getNewExpressionFromCommandLine();
      if (expression != null) {
        var statusFile = getStatusFile(_currentWorkingItem);
        addExpressionToCustomSections(expression, statusFile.path);
      }
    } else if (input == "c") {
      // Change comment.
      _currentWorkingItem.comment = getNewComment();
      _lastComment = _currentWorkingItem.comment;
    } else if (input == "f") {
      // Fix failing tests and try to fix the coming ones.
      await fixFailingTest();
      return _fixAllSimilarTests();
    } else if (input == "o") {
      // Case change new outcome.
      _currentWorkingItem.newOutcome = getNewOutcome();
    } else if (input == "r") {
      // Case reset.
      _currentWorkingItem.init();
    } else if (input == "s") {
      // Case reset.
      return new NavigateStepWorkflowAction(this, _remainingTests);
    } else {
      error = true;
    }
    var toggleMatch = toggleSectionRegExp.firstMatch(input);
    if (toggleMatch != null) {
      var index = int.parse(toggleMatch.group(1));
      error = !_currentWorkingItem.toggleSection(index);
    }
    if (error) {
      print("Input was not correct. Please try again.");
    } else {
      askAboutTest();
    }
    return new WaitForInputWorkflowAction();
  }

  Future<WorkflowAction> _fixAllSimilarTests() async {
    var unhandledTests = <FailingTest>[];
    for (FailingTest similarTest in _remainingTests) {
      _currentWorkingItem = new FixWorkingItem(similarTest.result.name,
          similarTest, _statusExpectations, _lastComment, this._customSections);
      _currentWorkingItem.init();
      // Outcome may be larger from the previous one, but current newOutcome
      // will always be a singleton list. So we check by matching first
      // element.
      var outcomeIsSame = _currentWorkingItem.newOutcome.first ==
          _lastWorkingItem.newOutcome.first;
      var lastConfigurations =
          _lastWorkingItem.failingTest.failingConfigurations;
      var currentConfigurations =
          _currentWorkingItem.failingTest.failingConfigurations;
      var sameConfigurations = lastConfigurations.length ==
              currentConfigurations.length &&
          lastConfigurations.every(
              (configuration) => currentConfigurations.contains(configuration));
      var sameFiles = _lastWorkingItem.statusFiles().every((last) {
        return _currentWorkingItem.statusFiles().any((current) {
          return current.path == last.path;
        });
      });
      if (outcomeIsSame && sameConfigurations && sameFiles) {
        _currentWorkingItem.currentSections = _lastWorkingItem.currentSections;
        print("Auto-fixing ${_currentWorkingItem.name}");
        var realLast = _lastWorkingItem;
        await fixFailingTest(); // Sets _lastWorkingItem to _currentWorkingItem
        _lastWorkingItem = realLast; // Might not be needed
      } else {
        unhandledTests.add(similarTest);
      }
    }
    return new NavigateStepWorkflowAction(this, unhandledTests);
  }

  @override
  Future<bool> onLeave() {
    return new Future.value(false);
  }

  /// Prints up to date data about [currentWorkItem] and gives information about
  /// the commands that can be used.
  void askAboutTest() {
    _currentWorkingItem.printInfo();
    print("");
    print("To modify the above data, the following commands are available:");
    print("<Enter> : Write new outcome to selected sections in status files.");
    print("a       : Add/Create section.");
    print("c       : Modify the comment.");
    print("f       : Write new outcome to selected sections in status files "
        "and try to fix remaining tests 'the same way'.");
    print("o       : Modify outcomes.");
    print("r       : Reset to initial state.");
    print("s       : Skip this failure.");
    print("<n>     : Toggle selection of the section with the index <n>.");
  }

  /// Fixes the failing test based on the data in [_currentWorkingItem].
  Future fixFailingTest() async {
    // Delete all existing entries that are wrong.
    var changedFiles = new Set<StatusFile>();
    for (var statusEntry in _currentWorkingItem.statusEntries) {
      statusEntry.section.entries.remove(statusEntry.entry);
      changedFiles.add(statusEntry.statusFile);
    }
    // Add new expectations to status sections.
    var path = getQualifiedNameForTest(_currentWorkingItem.name);
    var expectations = _currentWorkingItem.newOutcome
        .map((outcome) => Expectation.find(outcome))
        .toList();
    var comment = _currentWorkingItem.comment == null
        ? null
        : new Comment(_currentWorkingItem.comment);
    var statusEntry = new StatusEntry(path, 0, expectations, comment);
    for (var currentSection in _currentWorkingItem.currentSections) {
      if (!currentSection.statusFile.sections
          .contains(currentSection.section)) {
        currentSection.statusFile.sections.add(currentSection.section);
      }
      currentSection.section.entries.insert(0, statusEntry);
      changedFiles.add(currentSection.statusFile);
    }
    // Save the modified status files.
    for (var file in changedFiles) {
      await new File(file.path)
          .writeAsString(normalizeStatusFile(file).toString());
    }
    _lastWorkingItem = _currentWorkingItem;
  }

  /// Tries to find a section with the [expression] in [statusFilePath]. If it
  /// cannot find a section, it will create a new section. It selects the new
  /// section on the [currentWorkItem].
  void addExpressionToCustomSections(
      Expression expression, String statusFilePath) {
    expression = expression.normalize();
    var statusFile = _currentWorkingItem
        .statusFiles()
        .firstWhere((statusFile) => statusFile.path == statusFilePath);
    var sectionToAdd = statusFile.sections.firstWhere(
        (section) =>
            section.condition != null &&
            section.condition.normalize().compareTo(expression) == 0,
        orElse: () => null);
    sectionToAdd ??= new StatusSection(expression, 0, [])
      ..entries.add(new EmptyEntry(0));
    var section = new StatusSectionWithFile(statusFile, sectionToAdd);
    _customSections.add(new _CustomSection(section));
    _currentWorkingItem.currentSections.add(section);
  }
}

/// Gets a new [Expression] from the commandline. The expression is parsed to
/// make sure it is syntactically correct. If no input is added it returns
/// [null].
Expression getNewExpressionFromCommandLine() {
  print("Write a new status header expression - <Enter> to cancel:");
  String input = stdin.readLineSync();
  if (input.isEmpty) {
    return null;
  }
  try {
    return Expression.parse(input);
  } catch (e) {
    print(e);
    return getNewExpressionFromCommandLine();
  }
}

/// Gets a status file by finding the suite from [workingItem] and asks the
/// user to pick the correct file.
StatusFile getStatusFile(FixWorkingItem workingItem) {
  var statusFiles = workingItem.statusFiles();
  if (statusFiles.length == 1) {
    return statusFiles.first;
  }
  print("Which status file should the section be added to/exists in?");
  int i = 0;
  for (var statusFile in statusFiles) {
    print("  ${i++}: ${statusFile.path}");
  }
  var input = stdin.readLineSync();
  var index = int.parse(input, onError: (_) => -1);
  if (index >= 0 && index < statusFiles.length) {
    return statusFiles[index];
  }
  print("Input was not between 0-$i. Please try again");
  return getStatusFile(workingItem);
}

/// Gets a new outcome from the user. The input is a list of strings, but every
/// element has been parsed to check if it is an expectation.
List<String> getNewOutcome() {
  print("Write new outcomes, separate by ',':");
  String input = stdin.readLineSync();
  try {
    var newOutcomes =
        input.split(",").map((outcome) => outcome.trim()).toList();
    newOutcomes.forEach((name) => Expectation.find(name));
    return newOutcomes;
  } catch (e) {
    print(e);
    return getNewOutcome();
  }
}

/// Gets a comment from the user. It automatically adds # if it is not entered
/// and checks if the input is a number, by which it assumes it is an issue.
String getNewComment() {
  print("Write a new comment or github issue. Empty for no comment:");
  String newComment = stdin.readLineSync();
  if (newComment.isEmpty) {
    return null;
  }
  if (int.parse(newComment, onError: (input) => null) != null) {
    return "# Issue $newComment";
  }
  if (!newComment.startsWith("#")) {
    newComment = "# $newComment";
  }
  return newComment;
}

/// [FixWorkingItem] holds the current data about what sections to update,
/// what configurations are covered, the comment, the outcomes etc.
class FixWorkingItem {
  final String name;
  final FailingTest failingTest;
  final StatusExpectations statusExpectations;

  Iterable<StatusSectionWithFile> customSections;
  List<StatusSectionWithFile> currentSections;
  List<SectionsSuggestion> suggestedSections;
  List<String> newOutcome;
  List<StatusSectionEntry> statusEntries;
  String comment;

  FixWorkingItem(this.name, this.failingTest, this.statusExpectations,
      this.comment, Iterable<_CustomSection> customSections) {
    var files = statusFiles();
    this.customSections = customSections.expand((customSection) {
      var sectionWithFile = customSection._findSection(currentSections);
      if (sectionWithFile != null) {
        return [sectionWithFile];
      }
      var file = customSection._findStatusFile(files);
      if (file != null) {
        var section = customSection._findSectionInFile(file);
        section ??= new StatusSection(customSection.condition, 0, [])
          ..entries.add(new EmptyEntry(0));
        return [new StatusSectionWithFile(file, section)];
      }
      return [];
    });
  }

  /// init resets all custom data to the standard values from the failing test,
  /// except the comment and custom added sections.
  void init() {
    newOutcome = [failingTest.result.result];
    statusEntries = failingTest.failingStatusEntries(statusExpectations);
    suggestedSections = failingTest.computeSections(statusExpectations);
    currentSections = [];
  }

  /// Gets the status files for the failing test.
  List<StatusFile> statusFiles() {
    return failingTest.statusFiles(statusExpectations);
  }

  /// Toggles the selection of a section by [index].
  bool toggleSection(int index) {
    var sections =
        suggestedSections.expand((suggested) => suggested.sections).toList();
    sections.addAll(customSections);
    if (index < 0 || index >= sections.length) {
      return false;
    }
    var section = sections[index];
    if (currentSections.contains(section)) {
      currentSections.remove(section);
    } else {
      currentSections.add(section);
    }
    return true;
  }

  /// Prints all information about the current working item.
  void printInfo() {
    print("");
    print("--- ${name} ---");
    print("New (o)utcome: ${newOutcome}");
    print("Failing configurations (covered configurations marked by *):");
    var failingNotCovered = failingTest.failingConfigurationsNotCovered(
        statusExpectations, currentSections);
    failingTest.failingConfigurations.forEach((configuration) {
      String selected = !failingNotCovered.contains(configuration) ? "* " : "";
      print("  $selected${configuration.toArgs(includeSelectors: false)}");
    });
    if (failingTest.passingConfigurations.isEmpty) {
      print("Passing configurations: None");
    } else {
      var passingNotCovered = failingTest.failingConfigurationsNotCovered(
          statusExpectations, currentSections);
      print("Passing configurations (covered configurations marked by x - this "
          "is generally not what you want):");
      failingTest.passingConfigurations.forEach((configuration) {
        String selected = passingNotCovered.contains(configuration) ? "x " : "";
        print("  $selected${configuration.toArgs(includeSelectors: false)}");
      });
    }
    var defaultExpectations =
        expectationsFromTest(failingTest.result.testExpectations);
    defaultExpectations.add(Expectation.pass);
    // Is the outcome the default expectation, i.e. should all entries should be
    // removed.
    bool isDefaultExpectation = newOutcome.length == 1 &&
        defaultExpectations.contains(Expectation.find(newOutcome.first));
    if (isDefaultExpectation) {
      print("The new outcome is the default expectation of the test file.");
    } else {
      _printSections();
    }
    if (statusEntries.isNotEmpty) {
      print("Status entries to be deleted:");
      _printStatusEntries(statusEntries);
    }
    print("Status entry (c)omment:");
    if (comment != null) {
      print("  ${comment}");
    }
  }

  void _printSections() {
    print("Sections to add the new outcome to. The selected sections are "
        "marked by *:");
    int groupCounter = "A".codeUnitAt(0);
    int sectionCounter = 0;
    suggestedSections.forEach((suggestedSection) {
      print("  ${new String.fromCharCode(groupCounter++)} "
          "(${suggestedSection.strategy}):");
      suggestedSection.sections
          .forEach((section) => _printSection(section, sectionCounter++));
    });
    print("  ${new String.fromCharCode(groupCounter)}: Added/Used sections");
    customSections
        .forEach((section) => _printSection(section, sectionCounter++));
  }

  void _printSection(StatusSectionWithFile section, int index) {
    String selected = currentSections.contains(section) ? "* " : "";
    print("    $selected${index}: ${section.statusFile.path}: "
        "[ ${section.section.condition.toString()} ]");
  }

  void _printStatusEntries(List<StatusSectionEntry> entries) {
    for (StatusSectionEntry entry in entries) {
      print("  ${entry.statusFile.path}");
      print("    [ ${entry.section.condition} ]");
      print("      line ${entry.entry.lineNumber}: ${entry.entry.path} : "
          "${entry.entry.expectations} ${entry.entry.comment ?? ""}");
    }
  }
}

class _CustomSection {
  final String path;
  final Expression condition;

  _CustomSection(StatusSectionWithFile section)
      : path = section.statusFile.path,
        condition = section.section.condition;

  StatusFile _findStatusFile(Iterable<StatusFile> files) {
    return files.firstWhere((f) => f.path == path, orElse: () => null);
  }

  StatusSection _findSectionInFile(StatusFile file) {
    return file.sections
        .firstWhere((s) => s.condition == condition, orElse: () => null);
  }

  StatusSectionWithFile _findSection(Iterable<StatusSectionWithFile> sections) {
    return sections.firstWhere((s) => s.section.condition == condition,
        orElse: () => null);
  }

  @override
  String toString() {
    return "{$path} [{$condition}]";
  }

  @override
  bool operator ==(other) {
    return other is _CustomSection && toString() == other.toString();
  }

  @override
  int get hashCode {
    return toString().hashCode;
  }
}
