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

/// Script that updates dart2js status lines automatically for tests under the
/// '$dart2js_with_kernel' configuration.
///
/// This script is hardcoded to only support this configuration and relies on
/// a convention for how the status files are structured, In particular,
/// every status file for dart2js should have 3 sections:
///
///     [ $compiler == dart2js && $dart2js_with_kernel && $host_checked ]
///
/// and:
///
///     [ $compiler == dart2js && $dart2js_with_kernel && $minified ]
///
/// and:
///
///     [ $compiler == dart2js && $dart2js_with_kernel && $fast_startup ]
///
/// and:
///
///     [ $compiler == dart2js && $checked && $dart2js_with_kernel ]
library compiler.status_files.update_from_log;

import 'dart:io';

import 'record.dart';
import 'log_parser.dart';

final dart2jsConfigurations = {
  'host-checked':
      r'[ $compiler == dart2js && $dart2js_with_kernel && $host_checked ]',
  'minified': r'[ $compiler == dart2js && $dart2js_with_kernel && $minified ]',
  'host-checked-strong':
      r'[ $compiler == dart2js && $dart2js_with_kernel && $host_checked && $strong ]',
  'minified-strong':
      r'[ $compiler == dart2js && $dart2js_with_kernel && $minified && $strong ]',
  'fast-startup':
      r'[ $compiler == dart2js && $dart2js_with_kernel && $fast_startup ]',
  'fast-startup-strong':
      r'[ $compiler == dart2js && $dart2js_with_kernel && $fast_startup && $strong ]',
  'checked-mode':
      r'[ $compiler == dart2js && $checked && $dart2js_with_kernel ]',
  'checked-mode-strong':
      r'[ $compiler == dart2js && $checked && $dart2js_with_kernel && $strong ]',
};

final dart2jsStatusFiles = {
  'language': 'tests/language/language_dart2js.status',
  'corelib': 'tests/corelib/corelib.status',
  'language_2': 'tests/language_2/language_2_dart2js.status',
  // TODO(sigmund,rnystrom): update when corelib_2 gets split into multiple
  // status files.
  'corelib_2': 'tests/corelib_2/corelib_2.status',
  'dart2js_extra': 'tests/compiler/dart2js_extra/dart2js_extra.status',
  'dart2js_native': 'tests/compiler/dart2js_native/dart2js_native.status',
  'html': 'tests/html/html.status',
};

main(args) {
  mainInternal(args, dart2jsConfigurations, dart2jsStatusFiles);
}

/// Note: this is called above and also from
/// pkg/front_end/tool/status_files/update_from_log.dart
mainInternal(List<String> args, Map<String, String> configurations,
    Map<String, String> statusFiles) {
  if (args.length < 2) {
    print('usage: update_from_log.dart <mode> log.txt [message-in-quotes]');
    print('  where mode is one of these values: ${configurations.keys}');
    exit(1);
  }
  var mode = args[0];
  if (!configurations.containsKey(mode)) {
    print('invalid mode: $mode, expected one in ${configurations.keys}');
    exit(1);
  }

  var uri =
      Uri.base.resolveUri(new Uri.file(args[1], windows: Platform.isWindows));
  var file = new File.fromUri(uri);
  if (!file.existsSync()) {
    print('file not found: $file');
    exit(1);
  }

  var globalReason = args.length > 2 ? args[2] : null;
  updateLogs(
      mode, file.readAsStringSync(), configurations, statusFiles, globalReason);
}

/// Update all status files based on the [log] records when running the compiler
/// in [mode]. If provided [globalReason] is added as a comment to new test
/// failures. If not, an automated reason might be extracted from the test
/// failure message.
void updateLogs(String mode, String log, Map<String, String> configurations,
    Map<String, String> statusFiles, String globalReason) {
  List<Record> records = parse(log);
  records.sort();
  var last;
  ConfigurationInSuiteSection section;
  for (var record in records) {
    if (last == record) continue; // ignore duplicates
    if (section?.suite != record.suite) {
      section?.update(globalReason);
      var statusFile = statusFiles[record.suite];
      if (statusFile == null) {
        print("No status file for suite '${record.suite}'.");
        continue;
      }
      var condition = configurations[mode];
      section = ConfigurationInSuiteSection.create(
          record.suite, mode, statusFile, condition);
    }
    section.add(record);
    last = record;
  }
  section?.update(globalReason);
}

/// Represents an existing entry in the logs.
class ExistingEntry {
  final String test;
  final String status;
  final bool hasComment;

  ExistingEntry(this.test, this.status, this.hasComment);

  static parse(String line) {
    var colonIndex = line.indexOf(':');
    var test = line.substring(0, colonIndex);
    var status = line.substring(colonIndex + 1).trim();
    var commentIndex = status.indexOf("#");
    if (commentIndex != -1) {
      status = status.substring(0, commentIndex);
    }
    return new ExistingEntry(test, status, commentIndex != -1);
  }
}

/// Represents a section in a .status file that corresponds to a specific suite
/// and configuration.
class ConfigurationInSuiteSection {
  final String suite;
  final String _statusFile;
  final String _contents;
  final int _begin;
  final int _end;
  final List<Record> _records = [];

  ConfigurationInSuiteSection(
      this.suite, this._statusFile, this._contents, this._begin, this._end);

  /// Add a new test record, indicating that the test status should be updated.
  void add(Record record) => _records.add(record);

  /// Update the section in the file.
  ///
  /// This will reflect the new status lines as recorded in [_records].
  void update(String providedReason) {
    int changes = 0;
    int ignored = 0;
    var originalEntries = _contents.substring(_begin, _end).split('\n');

    // The algorithm below walks entries in the file and from the log in the
    // same order: preserving entries that didn't change, and updating entries
    // where the logs show that the test status changed.

    // Sort the file contents in case the file has been tampered with.
    originalEntries.sort();

    /// Re-sort records by name (they came sorted by suite and status first, so
    /// it may be wrong for the merging below).
    _records.sort((a, b) => a.test.compareTo(b.test));

    var newContents = new StringBuffer();
    newContents.write(_contents.substring(0, _begin));
    addFromRecord(Record record) {
      var reason = providedReason ?? record.reason;
      var comment = reason != null && reason.isNotEmpty ? ' # ${reason}' : '';
      newContents.writeln('${record.test}: ${record.actual}$comment');
    }

    int i = 0, j = 0;
    while (i < originalEntries.length && j < _records.length) {
      var existingLine = originalEntries[i];
      if (existingLine.trim().isEmpty) {
        i++;
        continue;
      }
      var existing = ExistingEntry.parse(existingLine);
      var record = _records[j];
      var compare = existing.test.compareTo(record.test);
      if (compare < 0) {
        // Existing test was unaffected, copy the status line.
        newContents.writeln(existingLine);
        i++;
      } else if (compare > 0) {
        // New entry, if it's a failure, we haven't seen this before and must
        // add it. If the status says it is passing, we ignore it. We do this
        // to support making this script idempotent if the patching has already
        // been done.
        if (!record.isPassing) {
          // New failure never seen before
          addFromRecord(record);
          changes++;
        }
        j++;
      } else if (existing.status == record.actual) {
        if (!existing.hasComment && record.reason != null) {
          addFromRecord(record);
          changes++;
        } else {
          // This also should only happen if the patching has already been done.
          // We don't complain to make this script idempotent.
          newContents.writeln(existingLine);
        }
        ignored++;
        i++;
        j++;
      } else {
        changes++;
        // The status changed, if it is now passing, we omit the entry entirely,
        // otherwise we use the status from the logs.
        if (!record.isPassing) {
          addFromRecord(record);
        }
        i++;
        j++;
      }
    }

    for (; i < originalEntries.length; i++) {
      newContents.writeln(originalEntries[i]);
    }

    for (; j < _records.length; j++) {
      changes++;
      addFromRecord(_records[j]);
    }

    newContents.write('\n');
    newContents.write(_contents.substring(_end));
    new File(_statusFile).writeAsStringSync('$newContents');
    print("updated '$_statusFile' with $changes changes");
    if (ignored > 0) {
      print('  $ignored changes were already applied in the status file.');
    }
  }

  static ConfigurationInSuiteSection create(
      String suite, String mode, String statusFile, String condition) {
    var contents = new File(statusFile).readAsStringSync();
    int sectionDeclaration = contents.indexOf(condition);
    if (sectionDeclaration == -1) {
      print('error: unable to find condition $condition in $statusFile');
      exit(1);
    }
    int begin = contents.indexOf('\n', sectionDeclaration) + 1;
    assert(begin != 0);
    int newlinePos = contents.indexOf('\n', begin + 1);
    int end = newlinePos;
    while (true) {
      if (newlinePos == -1) break;
      if (newlinePos + 1 < contents.length) {
        if (contents[newlinePos + 1] == '[') {
          // We've found the end of the section
          break;
        } else if (contents[newlinePos + 1] == '#') {
          // We've found a commented out line.  This line might belong to the
          // next section.
          newlinePos = contents.indexOf('\n', newlinePos + 1);
          continue;
        }
      }
      // We've found an ordinary line.  It's part of this section, so update
      // end.
      newlinePos = contents.indexOf('\n', newlinePos + 1);
      end = newlinePos;
    }
    end = end == -1 ? contents.length : end + 1;
    return new ConfigurationInSuiteSection(
        suite, statusFile, contents, begin, end);
  }
}
