// Copyright 2016 The Chromium Authors. 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:flutter/material.dart';
import 'package:test/test.dart';

import 'finders.dart';

/// Asserts that the [Finder] matches no widgets in the widget tree.
///
/// Example:
///
///     expect(find.text('Save'), findsNothing);
const Matcher findsNothing = const _FindsWidgetMatcher(null, 0);

/// Asserts that the [Finder] locates at least one widget in the widget tree.
///
/// Example:
///
///     expect(find.text('Save'), findsWidgets);
const Matcher findsWidgets = const _FindsWidgetMatcher(1, null);

/// Asserts that the [Finder] locates at exactly one widget in the widget tree.
///
/// Example:
///
///     expect(find.text('Save'), findsOneWidget);
const Matcher findsOneWidget = const _FindsWidgetMatcher(1, 1);

/// Asserts that the [Finder] locates the specified number of widgets in the widget tree.
///
/// Example:
///
///     expect(find.text('Save'), findsNWidgets(2));
Matcher findsNWidgets(int n) => new _FindsWidgetMatcher(n, n);

/// Asserts that the [Finder] locates the a single widget that has at
/// least one [OffStage] widget ancestor.
const Matcher isOffStage = const _IsOffStage();

/// Asserts that the [Finder] locates the a single widget that has no
/// [OffStage] widget ancestors.
const Matcher isOnStage = const _IsOnStage();

/// Asserts that the [Finder] locates the a single widget that has at
/// least one [Card] widget ancestor.
const Matcher isInCard = const _IsInCard();

/// Asserts that the [Finder] locates the a single widget that has no
/// [Card] widget ancestors.
const Matcher isNotInCard = const _IsNotInCard();

/// Asserts that an object's toString() is a plausible one-line description.
///
/// Specifically, this matcher checks that the string does not contains newline
/// characters and does not have leading or trailing whitespace.
const Matcher hasOneLineDescription = const _HasOneLineDescription();

class _FindsWidgetMatcher extends Matcher {
  const _FindsWidgetMatcher(this.min, this.max);

  final int min;
  final int max;

  @override
  bool matches(Finder finder, Map<dynamic, dynamic> matchState) {
    assert(min != null || max != null);
    matchState[Finder] = finder;
    if (min != null) {
      int count = 0;
      Iterator<Element> iterator = finder.evaluate().iterator;
      while (count < min && iterator.moveNext())
        count += 1;
      if (count < min)
        return false;
    }
    if (max != null) {
      int count = 0;
      Iterator<Element> iterator = finder.evaluate().iterator;
      while (count <= max && iterator.moveNext())
        count += 1;
      if (count > max)
        return false;
    }
    return true;
  }

  @override
  Description describe(Description description) {
    assert(min != null || max != null);
    if (min == max) {
      if (min == 1)
        return description.add('exactly one matching node in the widget tree');
      return description.add('exactly $min matching nodes in the widget tree');
    }
    if (min == null) {
      if (max == 0)
        return description.add('no matching nodes in the widget tree');
      if (max == 1)
        return description.add('at most one matching node in the widget tree');
      return description.add('at most $max matching nodes in the widget tree');
    }
    if (max == null) {
      if (min == 1)
        return description.add('at least one matching node in the widget tree');
      return description.add('at least $min matching nodes in the widget tree');
    }
    return description.add('between $min and $max matching nodes in the widget tree (inclusive)');
  }

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose
  ) {
    Finder finder = matchState[Finder];
    int count = finder.evaluate().length;
    if (count == 0) {
      assert(min != null && min > 0);
      if (min == 1 && max == 1)
        return mismatchDescription.add('means none were found but one was expected');
      return mismatchDescription.add('means none were found but some were expected');
    }
    if (max == 0) {
      if (count == 1)
        return mismatchDescription.add('means one was found but none were expected');
      return mismatchDescription.add('means some were found but none were expected');
    }
    if (min != null && count < min)
      return mismatchDescription.add('is not enough');
    assert(max != null && count > min);
    return mismatchDescription.add('is too many');
  }
}

bool _hasAncestorOfType(Finder finder, Type targetType) {
  expect(finder, findsOneWidget);
  bool result = false;
  finder.evaluate().single.visitAncestorElements((Element ancestor) {
    if (ancestor.widget.runtimeType == targetType) {
      result = true;
      return false;
    }
    return true;
  });
  return result;
}

class _IsOffStage extends Matcher {
  const _IsOffStage();

  @override
  bool matches(Finder finder, Map<dynamic, dynamic> matchState) => _hasAncestorOfType(finder, OffStage);

  @override
  Description describe(Description description) => description.add('offstage');
}

class _IsOnStage extends Matcher {
  const _IsOnStage();

  @override
  bool matches(Finder finder, Map<dynamic, dynamic> matchState) => !_hasAncestorOfType(finder, OffStage);

  @override
  Description describe(Description description) => description.add('onstage');
}

class _IsInCard extends Matcher {
  const _IsInCard();

  @override
  bool matches(Finder finder, Map<dynamic, dynamic> matchState) => _hasAncestorOfType(finder, Card);

  @override
  Description describe(Description description) => description.add('in card');
}

class _IsNotInCard extends Matcher {
  const _IsNotInCard();

  @override
  bool matches(Finder finder, Map<dynamic, dynamic> matchState) => !_hasAncestorOfType(finder, Card);

  @override
  Description describe(Description description) => description.add('not in card');
}

class _HasOneLineDescription extends Matcher {
  const _HasOneLineDescription();

  @override
  bool matches(Object object, Map<dynamic, dynamic> matchState) {
    String description = object.toString();
    return description.isNotEmpty &&
        !description.contains('\n') &&
        description.trim() == description;
  }

  @override
  Description describe(Description description) => description.add('one line description');
}
