// 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 'package:path/path.dart' as p;

import 'editable_status_file.dart';
import 'fork.dart';
import 'io.dart';
import 'log.dart';
import 'test_directories.dart';

/// Migrates the status file entries that match [files].
void migrateStatusEntries(List<Fork> files, Map<String, List<String>> todos) {
  var entriesToMove = new EntrySet();

  _collectEntries(files, entriesToMove, isOne: true);
  _collectEntries(files, entriesToMove, isOne: false);

  for (var statusFile in entriesToMove.statusFiles) {
    var sections = entriesToMove.sections(statusFile);
    _addEntries(statusFile, sections);
  }

  // If any entries need manual splitting, let the user know.
  for (var statusFile in entriesToMove._todoHeaders.keys) {
    var headers = entriesToMove._todoHeaders[statusFile];
    var splits = headers.map((header) {
      var files = filesForHeader(header).map((file) => bold(file)).join(", ");
      return "Manually split status file section across $files status files:\n"
          "    $header";
    }).toList();

    if (splits.isNotEmpty) todos[statusFile] = splits;
  }
}

/// Given the header for a status file section, looks at the condition
/// expression to determine which status files it should go in.
Set<String> filesForHeader(String header) {
  // Figure out which status file it goes into.
  var result = new Set<String>();

  // The various compilers are roughly separate products.
  const compilers = const {
    r"$compiler == dart2analyzer": "analyzer",
    r"$compiler == dart2js": "dart2js",
    r"$compiler == dartdevc": "dartdevc",
    // This deliberately matches both dartk and dartkp.
    r"$compiler == dartk": "kernel",
    r"$compiler == precompiler": "precompiled"
  };

  // TODO(rnystrom): This is obviously very sensitive to the formatting of
  // the expression. Hacky, but hopefully good enough for now.
  compilers.forEach((compiler, file) {
    if (header.contains(compiler)) result.add(file);
  });

  // If we couldn't figure out where to put it based on the compiler, look at
  // the runtime.
  if (result.isEmpty) {
    const runtimes = const {
      r"$runtime == vm": "vm",
      r"$runtime == flutter": "flutter",
      r"$runtime == dart_precompiled": "precompiled",
    };

    runtimes.forEach((runtime, file) {
      if (header.contains(runtime)) result.add(file);
    });
  }

  return result;
}

/// Tracks a set of entries to add to a set of Dart 2.0 status files.
class EntrySet {
  /// Keys are the names of the Dart 2.0 status file that will receive the
  /// entries. The value for each key is a map of section headers to the list
  /// of entries to add under that section.
  final Map<String, Map<String, List<String>>> _files = {};

  final _todoHeaders = <String, Set<String>>{};

  Iterable<String> get statusFiles => _files.keys;

  /// Attempts to add the [entry] under [header] in a status file in [fromDir]
  /// to this EntrySet.
  ///
  /// Returns true if successful or false if the header's condition doesn't fit
  /// into a single status file and needs to be manually split by the user.
  bool add(String fromFile, String fromDir, String header, String entry) {
    var toDir;

    // Since we're migrating isolate and html directories into lib_2 instead of
    // isolate_2 and html_2, the status file entries are moved from
    // {isolate,html}.status -> lib_2_*.status. This checks to see if we're
    // handling these special directories and sets the 'to directory' to lib_2
    // instead of isolate_2 or html_2.
    if ((fromDir == "isolate") || (fromDir == "html")) {
      toDir = "lib_2";
      entry = p.join(fromDir, entry);
    } else {
      toDir = toTwoDirectory(fromDir);
    }

    // Figure out which status file it goes into.
    var possibleFiles = filesForHeader(header);
    var destination = "$toDir.status";
    if (possibleFiles.length > 1) {
      // The condition matches multiple files, so the user is going to have to
      // manually split it up into multiple sections first.
      // TODO(rnystrom): Would be good to automate this, though it requires
      // being able to work with condition expressions directly.
      var statusRelative = p.relative(fromFile, from: testRoot);
      _todoHeaders.putIfAbsent(statusRelative, () => new Set()).add(header);
      return false;
    }

    // The main "_strong.status" files skip lots of tests that are or were not
    // strong mode clean. We don't want to skip those tests in 2.0 -- we want
    // to fix them. If we're in that header, do remove the entry from the old
    // file, but don't add it to the new one.
    if (header == "[ \$strong ]") return true;

    // If the condition places it directly into one file, put it there.
    if (possibleFiles.length == 1) {
      destination = "${toDir}_${possibleFiles.single}.status";
    }

    var sections = _files.putIfAbsent(p.join(toDir, destination), () => {});
    var entries = sections.putIfAbsent(header, () => []);

    entries.add(entry);
    return true;
  }

  Map<String, List<String>> sections(String file) => _files[file];
}

/// Removes entries from the 1.0 and strong status files that correspond to
/// the list of [files] being migrated.
///
/// Adds moved entries to [entriesToMove].
void _collectEntries(List<Fork> files, EntrySet entriesToMove, {bool isOne}) {
  // Map the files to the way they will appear in the status file.
  var filePaths = files
      .map((fork) => p.withoutExtension(isOne ? fork.onePath : fork.strongPath))
      .toList();

  for (var fromDir in isOne ? oneRootDirs : strongRootDirs) {
    for (var path in listFiles(fromDir, extensions: [".status"])) {
      // Don't copy entries from the special "_parser" status files because
      // they use an unsupported compiler name.
      if (path.contains("_parser.status")) continue;

      var editable = new EditableStatusFile(path);

      var deleteLines = <int>[];
      for (var section in editable.statusFile.sections) {
        // TODO(rnystrom): For now, we don't support entries in the initial
        // implicit section at the top of the file. Do we need to?
        if (section.condition == null) continue;

        for (var entry in section.entries) {
          var entryPath = p.join(fromDir, entry.path);

          for (var filePath in filePaths) {
            // We only support entries that precisely match the file being
            // migrated, or a multitest within that. In both cases, the entry
            // path will begin with the full path of the file. We don't migrate
            // directory or glob patterns because those may also match other
            // files that have not been migrated yet.
            // TODO(rnystrom): It would be good to detect when a glob matches
            // a migrated file and let the user know that they may need to
            // manually handle it.
            if (!entryPath.startsWith(filePath)) continue;

            // Add it to the 2.0 one.
            if (entriesToMove.add(
                path,
                fromDir,
                editable.lineAt(section.lineNumber),
                editable.lineAt(entry.lineNumber))) {
              // Remove it from the original status file.
              deleteLines.add(entry.lineNumber - 1);
            }
          }
        }
      }

      // TODO(rnystrom): If all of the entries are deleted from a section, it
      // would be nice to delete the section header too.
      // We don't delete entries from the 1.0 status files so that we can keep
      // testing 1.0, but we do from the "_strong" directories since those
      // should get migrated fully into "_2".
      if (!isOne) editable.delete(deleteLines);
    }
  }
}

/// Adds all of [entries] to the status file at [path].
///
/// If the status file already has a section that matches a header in [entries],
/// then adds those entries to the end of that section. Otherwise, appends a
/// new section to the end of the file.
void _addEntries(String path, Map<String, List<String>> entries) {
  var editable = new EditableStatusFile(p.join(testRoot, path));

  for (var header in entries.keys) {
    var found = false;

    // Look for an existing section with the same header to add it to.
    for (var section in editable.statusFile.sections) {
      if (header == editable.lineAt(section.lineNumber)) {
        var line = section.lineNumber;
        // Add after existing entries, if there are any.
        if (section.entries.isNotEmpty) {
          line = section.entries.last.lineNumber;
        }

        editable.insert(line, entries[header]);
        found = true;
        break;
      }
    }

    if (!found) {
      // This section doesn't exist in the status file, so add it.
      editable.append(header, entries[header]);
    }
  }
}
