// 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.

library status_clean;

import "dart:async";
import "dart:convert" show json, utf8;
import "dart:io";
import "testing/dart/multitest.dart";
import "testing/dart/status_file_parser.dart";
import "testing/dart/test_suite.dart"
    show
        multiHtmlTestGroupRegExp,
        multiTestRegExp,
        multiHtmlTestRegExp,
        TestUtils;
import "testing/dart/utils.dart" show Path;

// [STATUS_TUPLES] is a list of (suite-name, directory, status-file)-tuples.
final STATUS_TUPLES = [
  ["corelib_2", "tests/corelib_2", "tests/corelib_2/corelib_2.status"],
  ["corelib", "tests/corelib", "tests/corelib/corelib.status"],
  ["html", "tests/html", "tests/html/html.status"],
  ["isolate", "tests/isolate", "tests/isolate/isolate.status"],
  ["language", "tests/language", "tests/language/language.status"],
  ["language", "tests/language", "tests/language/language_analyzer2.status"],
  ["language", "tests/language", "tests/language/language_analyzer.status"],
  ["language", "tests/language", "tests/language/language_dart2js.status"],
  ["lib", "tests/lib", "tests/lib/lib.status"],
  ["standalone", "tests/standalone", "tests/standalone/standalone.status"],
  ["pkg", "pkg", "pkg/pkg.status"],
  ["utils", "tests/utils", "tests/utils/utils.status"],
  ["samples", "samples", "samples/samples.status"],
  ["analyze_library", "sdk", "tests/lib/analyzer/analyze_library.status"],
  [
    "dart2js_extra",
    "tests/compiler/dart2js_extra",
    "tests/compiler/dart2js_extra/dart2js_extra.status"
  ],
  [
    "dart2js_native",
    "tests/compiler/dart2js_native",
    "tests/compiler/dart2js_native/dart2js_native.status"
  ],
  [
    "dart2js",
    "tests/compiler/dart2js",
    "tests/compiler/dart2js/dart2js.status"
  ],
  [
    "benchmark_smoke",
    "tests/benchmark_smoke",
    "tests/benchmark_smoke/benchmark_smoke.status"
  ],
  ["co19", "tests/co19/src", "tests/co19/co19-analyzer2.status"],
  ["co19", "tests/co19/src", "tests/co19/co19-analyzer.status"],
  ["co19", "tests/co19/src", "tests/co19/co19-dart2js.status"],
  ["co19", "tests/co19/src", "tests/co19/co19-co19.status"],
  ["co19", "tests/co19/src", "tests/co19/co19-dartium.status"],
  ["co19", "tests/co19/src", "tests/co19/co19-runtime.status"],
];

void main(List<String> args) {
  TestUtils.setDartDirUri(Platform.script.resolve('..'));
  usage() {
    print("Usage: ${Platform.executable} <deflake|remove-nonexistent-tests>");
    exit(1);
  }

  if (args.length == 0) usage();

  if (args[0] == 'deflake') {
    run(new StatusFileDeflaker());
  } else if (args[0] == 'remove-nonexistent-tests') {
    run(new StatusFileNonExistentTestRemover());
  } else {
    usage();
  }
}

run(StatusFileProcessor processor) {
  Future.forEach(STATUS_TUPLES, (List tuple) {
    String suiteName = tuple[0];
    String directory = tuple[1];
    String filePath = tuple[2];
    print("Processing $filePath");
    return processor.run(suiteName, directory, filePath);
  });
}

abstract class StatusFileProcessor {
  Future run(String suiteName, String directory, String filePath);

  Future<List<Section>> _readSections(String filePath) {
    File file = new File(filePath);

    if (file.existsSync()) {
      var completer = new Completer();
      List<Section> sections = new List<Section>();

      ReadConfigurationInto(new Path(file.path), sections, () {
        completer.complete(sections);
      });
      return completer.future;
    }
    return new Future.value([]);
  }
}

class StatusFileNonExistentTestRemover extends StatusFileProcessor {
  final MultiTestDetector multiTestDetector = new MultiTestDetector();
  final TestFileLister testFileLister = new TestFileLister();

  Future run(String suiteName, String directory, String filePath) {
    return _readSections(filePath).then((List<Section> sections) {
      Set<int> invalidLines = _analyzeStatusFile(directory, filePath, sections);
      if (invalidLines.length > 0) {
        return _writeFixedStatusFile(filePath, invalidLines);
      }
      return new Future.value();
    });
  }

  bool _testExists(String filePath, List<String> testFiles, String directory,
      TestRule rule) {
    // TODO: Unify this regular expression matching with status_file_parser.dart
    List<RegExp> getRuleRegex(String name) {
      return name
          .split("/")
          .map((name) => new RegExp(name.replaceAll('*', '.*')))
          .toList();
    }

    bool matchRegexp(List<RegExp> patterns, String str) {
      var parts = str.split("/");
      if (patterns.length > parts.length) {
        return false;
      }
      // NOTE: patterns.length <= parts.length
      for (var i = 0; i < patterns.length; i++) {
        if (!patterns[i].hasMatch(parts[i])) {
          return false;
        }
      }
      return true;
    }

    var rulePattern = getRuleRegex(rule.name);
    return testFiles.any((String file) {
      // TODO: Use test_suite.dart's [buildTestCaseDisplayName] instead.
      var filePath = new Path(file).relativeTo(new Path(directory));
      String baseTestName = _concat(
          "${filePath.directoryPath}", "${filePath.filenameWithoutExtension}");

      List<String> testNames = [];
      for (var name in multiTestDetector.getMultitestNames(file)) {
        testNames.add(_concat(baseTestName, name));
      }

      // If it is not a multitest the testname is [baseTestName]
      if (testNames.isEmpty) {
        testNames.add(baseTestName);
      }

      return testNames
          .any((String testName) => matchRegexp(rulePattern, testName));
    });
  }

  Set<int> _analyzeStatusFile(
      String directory, String filePath, List<Section> sections) {
    var invalidLines = new Set<int>();
    var dartFiles = testFileLister.listTestFiles(directory);
    for (var section in sections) {
      for (var rule in section.testRules) {
        if (!_testExists(filePath, dartFiles, directory, rule)) {
          print("Invalid rule: ${rule.name} in file "
              "$filePath:${rule.lineNumber}");
          invalidLines.add(rule.lineNumber);
        }
      }
    }
    return invalidLines;
  }

  _writeFixedStatusFile(String statusFilePath, Set<int> invalidLines) {
    var lines = new File(statusFilePath).readAsLinesSync();
    var outputLines = <String>[];
    for (int i = 0; i < lines.length; i++) {
      // The status file parser numbers lines starting with 1, not 0.
      if (!invalidLines.contains(i + 1)) {
        outputLines.add(lines[i]);
      }
    }
    var outputFile = new File("$statusFilePath.fixed");
    outputFile.writeAsStringSync(outputLines.join("\n"));
  }

  String _concat(String base, String part) {
    if (base == "") return part;
    if (part == "") return base;
    return "$base/$part";
  }
}

class StatusFileDeflaker extends StatusFileProcessor {
  TestOutcomeFetcher _testOutcomeFetcher = new TestOutcomeFetcher();

  Future run(String suiteName, String directory, String filePath) {
    return _readSections(filePath).then((List<Section> sections) {
      return _generatedDeflakedLines(suiteName, sections)
          .then((Map<int, String> fixedLines) {
        if (fixedLines.length > 0) {
          return _writeFixedStatusFile(filePath, fixedLines);
        }
      });
    });
  }

  Future _generatedDeflakedLines(String suiteName, List<Section> sections) {
    var fixedLines = new Map<int, String>();
    return Future.forEach(sections, (Section section) {
      return Future.forEach(section.testRules, (rule) {
        return _maybeFixStatusfileLine(suiteName, section, rule, fixedLines);
      });
    }).then((_) => fixedLines);
  }

  Future _maybeFixStatusfileLine(String suiteName, Section section,
      TestRule rule, Map<int, String> fixedLines) {
    print("Processing ${section.statusFile.location}: ${rule.lineNumber}");
    // None of our status file lines have expressions, so we pass {} here.
    var notedOutcomes = rule.expression
        .evaluate({})
        .map((name) => Expectation.byName(name))
        .where((Expectation expectation) => !expectation.isMetaExpectation)
        .toSet();

    if (notedOutcomes.isEmpty) return new Future.value();

    // TODO: [rule.name] is actually a pattern not just a testname. We should
    // find all possible testnames this rule matches against and unify the
    // outcomes of these tests.
    return _testOutcomeFetcher
        .outcomesOf(suiteName, section, rule.name)
        .then((Set<Expectation> actualOutcomes) {
      var outcomesThatNeverHappened = new Set<Expectation>();
      for (Expectation notedOutcome in notedOutcomes) {
        bool found = false;
        for (Expectation actualOutcome in actualOutcomes) {
          if (actualOutcome.canBeOutcomeOf(notedOutcome)) {
            found = true;
            break;
          }
        }
        if (!found) {
          outcomesThatNeverHappened.add(notedOutcome);
        }
      }

      if (outcomesThatNeverHappened.length > 0 && actualOutcomes.length > 0) {
        // Print the change to stdout.
        print("${rule.name} "
            "(${section.statusFile.location}:${rule.lineNumber}):");
        print("   Actual outcomes:         ${actualOutcomes.toList()}");
        print("   Outcomes in status file: ${notedOutcomes.toList()}");
        print("   Outcomes in status file that never happened : "
            "${outcomesThatNeverHappened.toList()}\n");

        // Build the fixed status file line.
        fixedLines[rule.lineNumber] =
            '${rule.name}: ${actualOutcomes.join(', ')} '
            '# before: ${notedOutcomes.join(', ')} / '
            'never happened:  ${outcomesThatNeverHappened.join(', ')}';
      }
    });
  }

  _writeFixedStatusFile(String filePath, Map<int, String> fixedLines) {
    var lines = new File(filePath).readAsLinesSync();
    var outputLines = <String>[];
    for (int i = 0; i < lines.length; i++) {
      if (fixedLines.containsKey(i + 1)) {
        outputLines.add(fixedLines[i + 1]);
      } else {
        outputLines.add(lines[i]);
      }
    }
    var output = outputLines.join("\n");
    var outputFile = new File("$filePath.deflaked");
    outputFile.writeAsStringSync(output);
  }
}

class MultiTestDetector {
  final multiTestsCache = new Map<String, List<String>>();
  final multiHtmlTestsCache = new Map<String, List<String>>();

  List<String> getMultitestNames(String file) {
    List<String> names = [];
    names.addAll(getStandardMultitestNames(file));
    names.addAll(getHtmlMultitestNames(file));
    return names;
  }

  List<String> getStandardMultitestNames(String file) {
    return multiTestsCache.putIfAbsent(file, () {
      try {
        var tests = new Map<String, String>();
        var outcomes = new Map<String, Set<String>>();
        if (multiTestRegExp.hasMatch(new File(file).readAsStringSync())) {
          extractTestsFromMultitest(new Path(file), tests, outcomes);
        }
        return tests.keys.toList();
      } catch (error) {
        print("WARNING: Couldn't determine multitests in file ${file}: $error");
        return [];
      }
    });
  }

  List<String> getHtmlMultitestNames(String file) {
    return multiHtmlTestsCache.putIfAbsent(file, () {
      try {
        List<String> subtestNames = [];
        var content = new File(file).readAsStringSync();

        if (multiHtmlTestRegExp.hasMatch(content)) {
          var matchesIter =
              multiHtmlTestGroupRegExp.allMatches(content).iterator;
          while (matchesIter.moveNext()) {
            String fullMatch = matchesIter.current.group(0);
            subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
          }
        }
        return subtestNames;
      } catch (error) {
        print("WARNING: Couldn't determine multitests in file ${file}: $error");
      }
      return [];
    });
  }
}

class TestFileLister {
  final Map<String, List<String>> _filesCache = {};

  List<String> listTestFiles(String directory) {
    return _filesCache.putIfAbsent(directory, () {
      var dir = new Directory(directory);
      // Cannot test for _test.dart because co19 tests don't have that ending.
      var dartFiles = dir
          .listSync(recursive: true)
          .where((fe) => fe is File)
          .where((file) =>
              file.path.endsWith(".dart") || file.path.endsWith("_test.html"))
          .map((file) => file.path)
          .toList();
      return dartFiles;
    });
  }
}

/*
 * [TestOutcomeFetcher] will fetch test results from a server using a REST-like
 * interface.
 */
class TestOutcomeFetcher {
  static String SERVER = '108.170.219.8';
  static int PORT = 4540;

  HttpClient _client = new HttpClient();

  Future<Set<Expectation>> outcomesOf(
      String suiteName, Section section, String testName) {
    var pathComponents = [
      'json',
      'test-outcomes',
      'outcomes',
      Uri.encodeComponent("$suiteName/$testName")
    ];
    var path = pathComponents.join('/') + '/';
    var url = new Uri(scheme: 'http', host: SERVER, port: PORT, path: path);

    return _client
        .getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
      return response
          .transform(utf8.decoder)
          .transform(json.decoder)
          .first
          .then((List testResults) {
        var setOfActualOutcomes = new Set<Expectation>();

        try {
          for (var result in testResults) {
            var config = result['configuration'];
            var testResult = result['test_result'];
            var outcome = testResult['outcome'];

            // These variables are derived variables and will be set in
            // tools/testing/dart/test_options.dart.
            // [Mostly due to the fact that we don't have an unary !
            //  operator in status file expressions.]
            config['unchecked'] = !config['checked'];
            config['unminified'] = !config['minified'];
            config['nocsp'] = !config['csp'];
            config['browser'] = TestUtils.isBrowserRuntime(config['runtime']);
            config['analyzer'] =
                TestUtils.isCommandLineAnalyzer(config['compiler']);
            config['jscl'] =
                TestUtils.isJsCommandLineRuntime(config['runtime']);

            if (section.condition == null ||
                section.condition.evaluate(config)) {
              setOfActualOutcomes.add(Expectation.byName(outcome));
            }
          }
          return setOfActualOutcomes;
        } catch (error) {
          print("Warning: Error occured while processing testoutcomes"
              ": $error");
          return [];
        }
      }).catchError((error) {
        print("Warning: Error occured while fetching testoutcomes: $error");
        return [];
      });
    });
  }
}
