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

import 'package:stack_trace/stack_trace.dart';

import 'description.dart';
import 'interfaces.dart';
import 'util.dart';

/// A useful utility class for implementing other matchers through inheritance.
/// Derived classes should call the base constructor with a feature name and
/// description, and an instance matcher, and should implement the
/// [featureValueOf] abstract method.
///
/// The feature description will typically describe the item and the feature,
/// while the feature name will just name the feature. For example, we may
/// have a Widget class where each Widget has a price; we could make a
/// [CustomMatcher] that can make assertions about prices with:
///
/// ```dart
/// class HasPrice extends CustomMatcher {
///   HasPrice(matcher) : super("Widget with price that is", "price", matcher);
///   featureValueOf(actual) => (actual as Widget).price;
/// }
/// ```
///
/// and then use this for example like:
///
/// ```dart
/// expect(inventoryItem, new HasPrice(greaterThan(0)));
/// ```
class CustomMatcher extends Matcher {
  final String _featureDescription;
  final String _featureName;
  final Matcher _matcher;

  CustomMatcher(this._featureDescription, this._featureName, matcher)
      : _matcher = wrapMatcher(matcher);

  /// Override this to extract the interesting feature.
  Object featureValueOf(actual) => actual;

  bool matches(item, Map matchState) {
    try {
      var f = featureValueOf(item);
      if (_matcher.matches(f, matchState)) return true;
      addStateInfo(matchState, {'custom.feature': f});
    } catch (exception, stack) {
      addStateInfo(matchState, {
        'custom.exception': exception.toString(),
        'custom.stack': new Chain.forTrace(stack)
            .foldFrames(
                (frame) =>
                    frame.package == 'test' ||
                    frame.package == 'stream_channel' ||
                    frame.package == 'matcher',
                terse: true)
            .toString()
      });
    }
    return false;
  }

  Description describe(Description description) =>
      description.add(_featureDescription).add(' ').addDescriptionOf(_matcher);

  Description describeMismatch(
      item, Description mismatchDescription, Map matchState, bool verbose) {
    if (matchState['custom.exception'] != null) {
      mismatchDescription
          .add('threw ')
          .addDescriptionOf(matchState['custom.exception'])
          .add('\n')
          .add(matchState['custom.stack'].toString());
      return mismatchDescription;
    }

    mismatchDescription
        .add('has ')
        .add(_featureName)
        .add(' with value ')
        .addDescriptionOf(matchState['custom.feature']);
    var innerDescription = new StringDescription();

    _matcher.describeMismatch(matchState['custom.feature'], innerDescription,
        matchState['state'] as Map, verbose);

    if (innerDescription.length > 0) {
      mismatchDescription.add(' which ').add(innerDescription.toString());
    }
    return mismatchDescription;
  }
}
