// 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"],
  ["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 [];
      });
    });
  }
}
