// Copyright (c) 2016, 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 'dart:html';
import 'dart:async';
import 'package:test/test.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/src/elements/sample_buffer_control.dart';
import '../mocks.dart';

main() {
  SampleBufferControlElement.tag.ensureRegistration();

  const vm = const VMMock();

  group('instantiation', () {
    SampleProfileLoadingProgressMock progress;
    StreamController<SampleProfileLoadingProgressEventMock> events;
    setUp(() {
      progress = new SampleProfileLoadingProgressMock();
      events = new StreamController<SampleProfileLoadingProgressEventMock>();
    });
    test('no additional parameters', () {
      final e = new SampleBufferControlElement(vm, progress, events.stream);
      expect(e, isNotNull, reason: 'element correctly created');
      expect(e.progress, equals(progress));
      expect(e.selectedTag, equals(M.SampleProfileTag.none));
      expect(e.showTag, isTrue);
    });
    test('selected tag', () {
      const tag = M.SampleProfileTag.userOnly;
      final e = new SampleBufferControlElement(vm, progress, events.stream,
          selectedTag: tag);
      expect(e, isNotNull, reason: 'element correctly created');
      expect(e.progress, equals(progress));
      expect(e.selectedTag, equals(tag));
      expect(e.showTag, isTrue);
    });
    test('show tag (true)', () {
      final e = new SampleBufferControlElement(vm, progress, events.stream,
          showTag: true);
      expect(e, isNotNull, reason: 'element correctly created');
      expect(e.progress, equals(progress));
      expect(e.selectedTag, equals(M.SampleProfileTag.none));
      expect(e.showTag, isTrue);
    });
    test('show tag (false)', () {
      final e = new SampleBufferControlElement(vm, progress, events.stream,
          showTag: false);
      expect(e, isNotNull, reason: 'element correctly created');
      expect(e.progress, equals(progress));
      expect(e.selectedTag, equals(M.SampleProfileTag.none));
      expect(e.showTag, isFalse);
    });
  });
  group('elements', () {
    SampleProfileLoadingProgressMock progress;
    StreamController<SampleProfileLoadingProgressEventMock> events;
    setUp(() {
      progress = new SampleProfileLoadingProgressMock();
      events = new StreamController<SampleProfileLoadingProgressEventMock>();
    });
    test('created after attachment', () async {
      final e = new SampleBufferControlElement(vm, progress, events.stream);
      document.body.append(e);
      await e.onRendered.first;
      expect(e.children.length, isNonZero, reason: 'has elements');
      e.remove();
      await e.onRendered.first;
      expect(e.children.length, isZero, reason: 'is empty');
    });
    test('listen for status changes', () async {
      final e = new SampleBufferControlElement(vm, progress, events.stream);
      expect(events.hasListener, isFalse);
      document.body.append(e);
      await e.onRendered.first;
      expect(events.hasListener, isTrue);
      events.add(new SampleProfileLoadingProgressEventMock(progress: progress));
      events.close();
      await e.onRendered.first;
      e.remove();
      await e.onRendered.first;
    });
    test('follow updates changes', () async {
      final e = new SampleBufferControlElement(vm, progress, events.stream);
      document.body.append(e);
      await e.onRendered.first;
      expect(e.querySelector('select'), isNull);
      events.add(new SampleProfileLoadingProgressEventMock(
          progress: new SampleProfileLoadingProgressMock(
              status: M.SampleProfileLoadingStatus.fetching)));
      await e.onRendered.first;
      expect(e.querySelector('select'), isNull);
      events.add(new SampleProfileLoadingProgressEventMock(
          progress: new SampleProfileLoadingProgressMock(
              status: M.SampleProfileLoadingStatus.loading)));
      await e.onRendered.first;
      expect(e.querySelector('select'), isNull);
      events.add(new SampleProfileLoadingProgressEventMock(
          progress: new SampleProfileLoadingProgressMock(
              status: M.SampleProfileLoadingStatus.loaded,
              profile: new SampleProfileMock())));
      events.close();
      await e.onRendered.first;
      expect(e.querySelector('select'), isNotNull);
      e.remove();
      await e.onRendered.first;
    });
    test('follow updates changes (no tag)', () async {
      final e = new SampleBufferControlElement(vm, progress, events.stream,
          showTag: false);
      document.body.append(e);
      await e.onRendered.first;
      expect(e.querySelector('select'), isNull);
      events.add(new SampleProfileLoadingProgressEventMock(
          progress: new SampleProfileLoadingProgressMock(
              status: M.SampleProfileLoadingStatus.fetching)));
      await e.onRendered.first;
      expect(e.querySelector('select'), isNull);
      events.add(new SampleProfileLoadingProgressEventMock(
          progress: new SampleProfileLoadingProgressMock(
              status: M.SampleProfileLoadingStatus.loading)));
      await e.onRendered.first;
      expect(e.querySelector('select'), isNull);
      events.add(new SampleProfileLoadingProgressEventMock(
          progress: new SampleProfileLoadingProgressMock(
              status: M.SampleProfileLoadingStatus.loaded,
              profile: new SampleProfileMock())));
      await e.onRendered.first;
      expect(e.querySelector('select'), isNull);
      e.remove();
      await e.onRendered.first;
    });
  });
  group('events', () {
    SampleProfileLoadingProgressMock progress;
    StreamController<SampleProfileLoadingProgressEventMock> events;
    setUp(() {
      progress = new SampleProfileLoadingProgressMock();
      events = new StreamController<SampleProfileLoadingProgressEventMock>();
    });
    test('onModeChange', () async {
      final e = new SampleBufferControlElement(vm, progress, events.stream);
      document.body.append(e);
      await e.onRendered.first;
      events.add(new SampleProfileLoadingProgressEventMock(
          progress: new SampleProfileLoadingProgressMock(
              status: M.SampleProfileLoadingStatus.loaded,
              profile: new SampleProfileMock())));
      await e.onRendered.first;
      expect(e.selectedTag, equals(M.SampleProfileTag.none));
      e.onTagChange.listen(expectAsync1((_) {
        expect(e.selectedTag, equals(M.SampleProfileTag.userOnly));
      }, count: 1));
      final select = (e.querySelector('.tag-select') as SelectElement);
      select.selectedIndex = select.options.indexOf((select.options.toSet()
            ..removeAll(select.selectedOptions))
          .toList()
          .first);
      select.dispatchEvent(new Event("change"));
      e.remove();
      await e.onRendered.first;
    });
  });
}
