// Copyright (c) 2012, 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_file_parser");

#import("dart:io");
#import("status_expression.dart");

/** Possible outcomes of running a test. */
const CRASH = "crash";
const TIMEOUT = "timeout";
const FAIL = "fail";
const PASS = "pass";
/**
 * An indication to skip the test.  The caller is responsible for skipping it.
 */
const SKIP = "skip";
const OK = "ok";
/**
 * An indication that a test is slow and we should allow extra time for
 * completion.
 */
const SLOW = "slow";

const RegExp StripComment = const RegExp("^[^#]*");
const RegExp HeaderPattern = const RegExp(r"^\[([^\]]+)\]");
const RegExp RulePattern = const RegExp(r"\s*([^: ]*)\s*:(.*)");

// TODO(whesse): Implement configuration_info library that contains data
// structures for test configuration, including Section.
class Section {
  BooleanExpression condition;
  List<TestRule> testRules;

  Section.always() : condition = null, testRules = new List<TestRule>();
  Section(this.condition) : testRules = new List<TestRule>();

  bool isEnabled(environment) =>
      condition == null || condition.evaluate(environment);
}

void ReadTestExpectationsInto(TestExpectations expectations,
                              String statusFilePath,
                              environment,
                              onDone) {
  List<Section> sections = new List<Section>();

  void sectionsRead() {
    for (Section section in sections) {
      if (section.isEnabled(environment)) {
        for (var rule in section.testRules) {
          expectations.addRule(rule, environment);
        }
      }
    }
    onDone();
  }

  ReadConfigurationInto(statusFilePath, sections, sectionsRead);
}

void ReadConfigurationInto(path, sections, onDone) {
  File file = new File(path);
  if (!file.existsSync()) {
    throw new Exception('Cannot find test status file $path');
  }
  InputStream file_stream = file.openInputStream();
  StringInputStream lines = new StringInputStream(file_stream);

  Section current = new Section.always();
  sections.add(current);

  lines.onLine = () {
    String line;
    while ((line = lines.readLine()) != null) {
      Match match = StripComment.firstMatch(line);
      line = (match == null) ? "" : match[0];
      line = line.trim();
      if (line.isEmpty()) continue;

      match = HeaderPattern.firstMatch(line);
      if (match != null) {
        String condition_string = match[1].trim();
        List<String> tokens = new Tokenizer(condition_string).tokenize();
        ExpressionParser parser = new ExpressionParser(new Scanner(tokens));
        current = new Section(parser.parseBooleanExpression());
        sections.add(current);
        continue;
      }

      match = RulePattern.firstMatch(line);
      if (match != null) {
        String name = match[1].trim();
        // TODO(whesse): Handle test names ending in a wildcard (*).
        String expression_string = match[2].trim();
        List<String> tokens = new Tokenizer(expression_string).tokenize();
        SetExpression expression =
            new ExpressionParser(new Scanner(tokens)).parseSetExpression();
        current.testRules.add(new TestRule(name, expression));
        continue;
      }

      print("unmatched line: $line");
    }
  };

  lines.onClosed = () {
    onDone();
  };
}


class TestRule {
  String name;
  SetExpression expression;

  TestRule(this.name, this.expression);

  String toString() => 'TestRule($name, $expression)';
}


class TestExpectations {
  Map _map;
  bool _preprocessed = false;
  Map _regExpCache;
  Map _keyToRegExps;

  /**
   * Create a TestExpectations object. See the [expectations] method
   * for an explanation of matching.
   */
  TestExpectations() : _map = new Map();

  /**
   * Add a rule to the expectations.
   */
  void addRule(testRule, environment) {
    // Once we have started using the expectations we cannot add more
    // rules.
    if (_preprocessed) {
      throw "TestExpectations.addRule: cannot add more rules";
    }
    var values = testRule.expression.evaluate(environment);
    _map.putIfAbsent(testRule.name, () => new Set()).addAll(values);
  }

  /**
   * Compute the expectations for a test based on the filename.
   *
   * For every (key, expectation) pair. Match the key with the file
   * name. Return the union of the expectations for all the keys
   * that match.
   *
   * Normal matching splits the key and the filename into path
   * components and checks that the anchored regular expression
   * "^$keyComponent\$" matches the corresponding filename component.
   */
  Set<String> expectations(String filename) {
    var result = new Set();
    var splitFilename = filename.split('/');

    // Create mapping from keys to list of RegExps once and for all.
    _preprocessForMatching();

    _map.forEach((key, expectation) {
      List regExps = _keyToRegExps[key];
      if (regExps.length > splitFilename.length) return;
      for (var i = 0; i < regExps.length; i++) {
        if (!regExps[i].hasMatch(splitFilename[i])) return;
      }
      // If all components of the status file key matches the filename
      // add the expectations to the result.
      result.addAll(expectation);
    });

    // If no expectations were found the expectation is that the test
    // passes.
    if (result.isEmpty()) {
      result.add(PASS);
    }
    return result;
  }

  // Preprocess the expectations for matching against
  // filenames. Generate lists of regular expressions once and for all
  // for each key.
  void _preprocessForMatching() {
    if (_preprocessed) return;

    _keyToRegExps = new Map();
    _regExpCache = new Map();

    _map.forEach((key, expectations) {
      if (_keyToRegExps[key] != null) return;
      var splitKey = key.split('/');
      var regExps = new List(splitKey.length);
      for (var i = 0; i < splitKey.length; i++) {
        var component = splitKey[i];
        var regExp = _regExpCache[component];
        if (regExp == null) {
          var pattern = "^${splitKey[i]}\$".replaceAll('*', '.*');
          regExp = new RegExp(pattern);
          _regExpCache[component] = regExp;
        }
        regExps[i] = regExp;
      }
      _keyToRegExps[key] = regExps;
    });

    _regExpCache = null;
    _preprocessed = true;
  }
}
