// 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:io';

import 'package:path/path.dart' as p;

import 'environment.dart';
import 'expectation.dart';
import 'status_file.dart';
import 'src/expression.dart';

/// Matches the header that begins a new section, like:
///
///     [ $compiler == dart2js && $minified ]
final RegExp _sectionPattern = RegExp(r"^\[(.+?)\]");

/// Matches an entry that defines the status for a path in the current section,
/// like:
///
///     some/path/to/some_test: Pass || Fail
final RegExp _entryPattern = RegExp(r"^([^:#]+):([^#]+)(#.*)?");

/// Matches an issue number in a comment, like:
///
///     blah_test: Fail # Issue 1234
///                       ^^^^
final RegExp _issuePattern = RegExp(r"[Ii]ssue (\d+)");

/// Matches a comment and indented comment, like:
///
///     < white space > #
final RegExp _commentPattern = RegExp(r"^(\s*)#");

/// A parsed status file, which describes how a collection of tests are
/// expected to behave under various configurations and conditions.
///
/// Each status file is made of a series of sections. Each section begins with
/// a header, followed by a series of entries. A header is enclosed in square
/// brackets and contains a Boolean expression. That expression is evaluated in
/// an environment. If it evaluates to true, then the entries after the header
/// take effect.
///
/// Each entry is a glob-like file path followed by a colon and then a
/// comma-separated list of [Expectation]s. The path is a regular expression
/// which may match one or more file or directory paths. If it matches a
/// directory path, it is considered to match all files in that directory or
/// (recursively) its subdirectories.
///
/// The intent is that status files will not have stand-alone comment lines. All
/// comments should be at the end of a single entry, and apply to that entry
/// only.
///
/// Until this is true for all status files, this program handles stand-alone
/// comment lines as follows:
///
/// 1) One or more comment lines immediately preceding a section header if there
/// is a linebreak from the previous section. Comment sections are added
/// directly to a section and are not entries.
/// 2) Comment lines anywhere else. These should be carefully removed when
/// found.
///
/// The reason for this distinction is to allow comments to be above sections,
/// without including these when lexicographically ordering section entries.
///
/// Entries may also appear before any section header, are considered to belong
/// to a default section, which always applies.
class StatusFile {
  final String path;
  final List<StatusSection> sections = [];

  int _lineCount = 1;

  /// Constructor for creating a new [StatusFile]. Will not create the default
  /// section that status files have.
  StatusFile(this.path);

  /// Reads and parses the status file at [path].
  ///
  /// Throws a [SyntaxError] if the file could not be parsed.
  StatusFile.read(this.path) {
    _parse(File(path).readAsLinesSync());
  }

  /// Parses lines of strings coming from a status file at [path].
  ///
  /// Throws a [SyntaxError] if the file could not be parsed.
  StatusFile.parse(this.path, List<String> lines) {
    _parse(lines.map((line) => line.trim()).toList());
  }

  void _parse(List<String> lines) {
    // We define a few helper functions that are used when parsing.

    /// Checks if [currentLine] is a comment and returns the first regular
    /// expression match, or null otherwise.
    Match? commentEntryMatch(int currentLine) {
      if (currentLine < 1 || currentLine > lines.length) {
        return null;
      }
      return _commentPattern.firstMatch(lines[currentLine - 1]);
    }

    /// Finds a section header on [currentLine] if the line is in range of
    /// [lines].
    Match? sectionHeaderMatch(int currentLine) {
      if (currentLine < 1 || currentLine > lines.length) {
        return null;
      }
      return _sectionPattern.firstMatch(lines[currentLine - 1]);
    }

    /// Checks if a line has a break from the previous section. A break is an
    /// empty line. It searches recursively until it find a break or a test
    /// entry.
    bool hasBreakFromPreviousSection(int currentLine) {
      if (currentLine <= 1) {
        return true;
      }

      var line = lines[currentLine - 1];
      if (line.isEmpty) {
        return true;
      }

      if (line.startsWith("#")) {
        return hasBreakFromPreviousSection(currentLine - 1);
      }

      return false;
    }

    /// Checks if comment on [currentLine] belongs to the next section.
    bool commentBelongsToNextSectionHeader(int currentLine) {
      if (currentLine >= lines.length ||
          commentEntryMatch(currentLine) == null) {
        return false;
      }
      return sectionHeaderMatch(currentLine + 1) != null ||
          commentBelongsToNextSectionHeader(currentLine + 1);
    }

    // List of comments added before the next section's header.
    List<Entry> sectionHeaderComments = [];

    // Parse file comments
    var lastEmptyLine = 0;
    for (; _lineCount <= lines.length; _lineCount++) {
      var line = lines[_lineCount - 1];
      if (!line.startsWith("#") && line.isNotEmpty) {
        break;
      }
      if (line.isEmpty) {
        sectionHeaderComments.add(EmptyEntry(_lineCount));
        lastEmptyLine = _lineCount;
      } else {
        sectionHeaderComments.add(CommentEntry(_lineCount, Comment(line)));
      }
    }

    var implicitSectionHeaderComments = sectionHeaderComments;
    var entries = <Entry>[];
    if (lastEmptyLine > 0 && sectionHeaderMatch(_lineCount) != null) {
      // Comments after the last empty line belong to the next section's header.
      // The empty line is not added to the section header, because it will be
      // added to the section's entries.
      implicitSectionHeaderComments =
          implicitSectionHeaderComments.sublist(0, lastEmptyLine - 1);
      entries.add(sectionHeaderComments[lastEmptyLine - 1]);
      sectionHeaderComments = sectionHeaderComments.sublist(lastEmptyLine);
    } else {
      // Reset section header comments.
      sectionHeaderComments = [];
    }

    // The current section whose rules are being parsed. Initialized to an
    // implicit section that matches everything.
    StatusSection section =
        StatusSection(Expression.always, -1, implicitSectionHeaderComments);
    section.entries.addAll(entries);
    sections.add(section);

    for (; _lineCount <= lines.length; _lineCount++) {
      var line = lines[_lineCount - 1];

      fail(String message, [List<String>? errors]) {
        throw SyntaxError(_shortPath, _lineCount, line, message, errors);
      }

      // If it is an empty line
      if (line.isEmpty) {
        section.entries.add(EmptyEntry(_lineCount));
        continue;
      }

      // See if we are starting a new section.
      var match = _sectionPattern.firstMatch(line);
      if (match != null) {
        try {
          var condition = Expression.parse(match[1]!.trim());
          section = StatusSection(condition, _lineCount, sectionHeaderComments);
          sections.add(section);
          // Reset section header comments.
          sectionHeaderComments = [];
        } on FormatException {
          fail("Status expression syntax error");
        }
        continue;
      }

      // If it is in a new entry we should add to the current section.
      match = _entryPattern.firstMatch(line);
      if (match != null) {
        var path = match[1]!.trim();
        var expectations = <Expectation>[];
        // split expectations
        match[2]!.split(",").forEach((name) {
          try {
            expectations.add(Expectation.find(name.trim()));
          } on ArgumentError {
            fail('Unrecognized test expectation "${name.trim()}"');
          }
        });
        if (match[3] == null) {
          section.entries
              .add(StatusEntry(path, _lineCount, expectations, null));
        } else {
          section.entries.add(
              StatusEntry(path, _lineCount, expectations, Comment(match[3]!)));
        }
        continue;
      }

      // If it is a comment, we have to find if it belongs with the current
      // section or the next section
      match = _commentPattern.firstMatch(line);
      if (match != null) {
        var commentEntry = CommentEntry(_lineCount, Comment(line));
        if (hasBreakFromPreviousSection(_lineCount) &&
            commentBelongsToNextSectionHeader(_lineCount)) {
          sectionHeaderComments.add(commentEntry);
        } else {
          section.entries.add(commentEntry);
        }
        continue;
      }

      fail("Unrecognized input");
    }

    // There are no comment entries in [sectionHeaderComments], because of the
    // check for [commentBelongsToSectionHeader].
    assert(sectionHeaderComments.isEmpty);
  }

  bool get isEmpty => sections.length == 1 && sections[0].isEmpty();

  /// Validates that the variables and values used in all of the section
  /// condition expressions are defined in [environment].
  ///
  /// Throws a [SyntaxError] on the first found error.
  void validate(Environment environment) {
    for (var section in sections) {
      var errors = <String>[];
      section.condition.validate(environment, errors);

      if (errors.isNotEmpty) {
        var s = errors.length > 1 ? "s" : "";
        throw SyntaxError(_shortPath, section.lineNumber,
            "[ ${section.condition} ]", 'Validation error$s', errors);
      }
    }
  }

  /// Gets the path to this status file relative to the Dart repo root.
  String get _shortPath {
    var repoRoot = p.fromUri(Platform.script.resolve('../../../'));
    return p.normalize(p.relative(path, from: repoRoot));
  }

  /// Returns the status file as a string. This preserves comments and gives a
  /// "canonical" rendering of the status file that can be saved back to disc.
  @override
  String toString() {
    var buffer = StringBuffer();
    sections.forEach(buffer.write);
    return buffer.toString();
  }
}

/// One section in a status file.
///
/// Contains the condition from the header that begins the section, then all of
/// the entries within the section.
class StatusSection {
  /// The expression that determines when this section is applied.
  ///
  /// Will be [Expression.always] for paths that appear before any section
  /// header in the file. In that case, the section always applies.
  final Expression condition;

  /// The one-based line number where the section appears in the file.
  final int lineNumber;

  /// Collection of all comment and status line entries.
  final List<Entry> entries = [];
  final List<Entry> sectionHeaderComments;

  /// Returns true if this section should apply in the given [environment].
  bool isEnabled(Environment environment) => condition.evaluate(environment);

  bool isEmpty() => !entries.any((entry) => entry is StatusEntry);

  StatusSection(this.condition, this.lineNumber, this.sectionHeaderComments);

  @override
  String toString() {
    var buffer = StringBuffer();
    sectionHeaderComments.forEach(buffer.writeln);
    if (condition != Expression.always) {
      buffer.writeln("[ $condition ]");
    }
    entries.forEach(buffer.writeln);
    return buffer.toString();
  }
}

class Comment {
  final String _comment;

  Comment(this._comment);

  /// Returns the issue number embedded in [comment] or `null` if there is none.
  int? issueNumber(String comment) {
    var match = _issuePattern.firstMatch(comment);
    if (match == null) return null;
    return int.parse(match[1]!);
  }

  @override
  String toString() {
    return _comment;
  }
}

abstract class Entry {
  /// The one-based line number where the entry appears in the file.
  final int lineNumber;
  Entry(this.lineNumber);
}

class EmptyEntry extends Entry {
  EmptyEntry(lineNumber) : super(lineNumber);

  @override
  String toString() {
    return "";
  }
}

class CommentEntry extends Entry {
  final Comment comment;
  CommentEntry(lineNumber, this.comment) : super(lineNumber);

  @override
  String toString() {
    return comment.toString();
  }
}

/// Describes the test status of the file or files at a given path.
class StatusEntry extends Entry {
  final String path;
  final List<Expectation> expectations;
  final Comment? comment;

  StatusEntry(this.path, lineNumber, this.expectations, this.comment)
      : super(lineNumber);

  @override
  String toString() {
    return comment == null
        ? "$path: ${expectations.join(', ')}"
        : "$path: ${expectations.join(', ')} $comment";
  }
}
