// Copyright (c) 2013, 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 descriptor.pattern;

import 'dart:async';
import 'dart:io';

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

import '../../descriptor.dart';
import '../../scheduled_test.dart';
import '../utils.dart';

/// A function that takes a name for a [Descriptor] and returns a [Descriptor].
/// This is used for [PatternDescriptor]s, where the name isn't known
/// ahead-of-time.
typedef Descriptor EntryCreator(String name);

/// A descriptor that matches filesystem entities by [Pattern] rather than
/// by [String]. It's used only for validation.
///
/// This class takes an [EntryCreator], which should return a [Descriptor] that
/// will be used to validate the concrete filesystem entities that match the
/// [pattern].
class PatternDescriptor extends Descriptor {
  /// The [Pattern] this matches filenames against. Note that the pattern must
  /// match the entire basename of the file.
  final Pattern pattern;

  /// The function used to generate the [Descriptor] for filesystem entities
  /// matching [pattern].
  final EntryCreator _fn;

  PatternDescriptor(Pattern pattern, this._fn)
      : super('$pattern'),
        pattern = pattern;

  /// Validates that there is some filesystem entity in [parent] that matches
  /// [pattern] and the child entry. This finds all entities in [parent]
  /// matching [pattern], then passes each of their names to the [EntityCreator]
  /// and validates the result. If exactly one succeeds, [this] is considered
  /// valid.
  Future validate([String parent]) => schedule(() => validateNow(parent),
      "validating ${describe()}");

  Future validateNow([String parent]) {
    if (parent == null) parent = defaultRoot;
    // TODO(nweiz): make sure this works with symlinks.
    var matchingEntries = new Directory(parent).listSync()
        .map((entry) => entry is File ? entry.resolveSymbolicLinksSync()
                                      : entry.path)
        .where((entry) => fullMatch(path.basename(entry), pattern))
        .toList();
    matchingEntries.sort();

    if (matchingEntries.isEmpty) {
      fail("No entry found in '$parent' matching ${_patternDescription}.");
    }

    return Future.wait(matchingEntries.map((entry) {
      var descriptor = _fn(path.basename(entry));
      return descriptor.validateNow(parent).then((_) {
        return new Pair(null, descriptor.describe());
      }).catchError((error) {
        return new Pair(error.toString(), descriptor.describe());
      });
    })).then((results) {
      var matches = results.where((result) => result.first == null).toList();
      // If exactly one entry matching [pattern] validated, we're happy.
      if (matches.length == 1) return;

      // If more than one entry matching [pattern] validated, that's bad.
      if (matches.length > 1) {
        var resultString = matches.map((result) {
          return prefixLines(result.last, firstPrefix: '* ', prefix: '  ');
        }).join('\n');

        fail("Multiple valid entries found in '$parent' matching "
             "$_patternDescription:\n"
             "$resultString");
      }

      // If no entries matching [pattern] validated, that's also bad.
      var resultString = results.map((result) {
        return prefixLines(
            "Caught error\n"
            "${prefixLines(result.first)}\n"
            "while validating\n"
            "${prefixLines(result.last)}",
            firstPrefix: '* ', prefix: '  ');
      }).join('\n');

      fail("No valid entries found in '$parent' matching "
           "$_patternDescription:\n"
           "$resultString");
    });
  }

  String describe() => "entry matching $_patternDescription";

  String get _patternDescription {
    if (pattern is String) return "'$pattern'";
    if (pattern is! RegExp) return '$pattern';

    var regExp = pattern as RegExp;
    var flags = new StringBuffer();
    if (!regExp.isCaseSensitive) flags.write('i');
    if (regExp.isMultiLine) flags.write('m');
    return '/${regExp.pattern}/$flags';
  }

  Future create([String parent]) => new Future.error(
      new UnsupportedError("Pattern descriptors don't support create()."));
}
