// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

library webdriver.support.async;

import 'dart:async' show Completer, Future;

import 'package:matcher/matcher.dart' as m;
import 'package:stack_trace/stack_trace.dart' show Chain;
import 'package:unittest/unittest.dart' as ut;

const defaultInterval = const Duration(milliseconds: 500);
const defaultTimeout = const Duration(seconds: 5);

const clock = const Clock();

Future waitFor(condition(),
        {matcher: null,
        Duration timeout: defaultTimeout,
        Duration interval: defaultInterval}) =>
    clock.waitFor(condition,
        matcher: matcher, timeout: timeout, interval: interval);

class Clock {
  const Clock();

  /// Sleep for the specified time.
  Future sleep([Duration interval = defaultInterval]) =>
      new Future.delayed(interval);

  /// The current time.
  DateTime get now => new DateTime.now();

  /// Waits until [condition] evaluates to a value that matches [matcher] or
  /// until [timeout] time has passed. If [condition] returns a [Future], then
  /// uses the value of that [Future] rather than the value of [condition].
  ///
  /// If the wait is successful, then the matching return value of [condition]
  /// is returned. Otherwise, if [condition] throws, then that exception is
  /// rethrown. If [condition] doesn't throw then an [expect] exception is
  /// thrown.
  Future waitFor(condition(),
      {matcher: null,
      Duration timeout: defaultTimeout,
      Duration interval: defaultInterval}) async {
    if (matcher != null && matcher is! ut.Matcher && matcher is! m.Matcher) {
      matcher = m.equals(matcher);
    }

    var endTime = now.add(timeout);
    while (true) {
      try {
        var value = await condition();
        if (matcher is m.Matcher) {
          _matcherExpect(value, matcher);
        } else if (matcher is ut.Matcher) {
          _unittestExpect(value, matcher);
        }
        return value;
      } catch (e) {
        if (now.isAfter(endTime)) {
          rethrow;
        } else {
          await sleep(interval);
        }
      }
    }
  }
}

_unittestExpect(value, ut.Matcher matcher) => ut.expect(value, matcher);

_matcherExpect(value, m.Matcher matcher) {
  var matchState = {};
  if (matcher.matches(value, matchState)) {
    return;
  }
  var desc = new m.StringDescription()
    ..add('Expected: ')
    ..addDescriptionOf(matcher)
    ..add('\n')
    ..add('  Actual: ')
    ..addDescriptionOf(value)
    ..add('\n');

  var mismatchDescription = new m.StringDescription();
  matcher.describeMismatch(value, mismatchDescription, matchState, true);
  if (mismatchDescription.length > 0) {
    desc.add('   Which: ${mismatchDescription}\n');
  }
  throw new Exception(desc.toString());
}

class Lock {
  Completer _lock;
  Chain _stack;

  final bool awaitChecking;

  Lock({this.awaitChecking: false});

  Future acquire() {
    if (awaitChecking) {
      if (isHeld) {
        return new Future.error(new StateError(
            'Maybe you missed an await? Lock is already held by:\n$_stack'));
      } else {
        _stack = new Chain.current().terse;
        _lock = new Completer();
        return new Future.value();
      }
    } else {
      return () async {
        while (isHeld) {
          await _lock.future;
        }
        _lock = new Completer();
      }();
    }
  }

  void release() {
    if (!isHeld) {
      throw new StateError('No lock to release');
    }
    _lock.complete();
    _lock = null;
    _stack = null;
  }

  bool get isHeld => _lock != null;
}
