// 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 custom_elements_test;
import 'dart:async';
import 'dart:html';
import 'package:unittest/html_individual_config.dart';
import 'package:unittest/unittest.dart';
import 'utils.dart';

class CustomMixin {
  var mixinMethodCalled;

  void mixinMethod() {
    mixinMethodCalled = true;
  }
}

class CustomType extends HtmlElement with CustomMixin{
  bool createdCalled = false;

  factory CustomType() => null;
  CustomType.created(): super.created() {
    createdCalled = true;
    customCreatedCount++;
  }

  void invokeMixinMethod() {
    mixinMethod();
  }
}

int customCreatedCount = 0;

int nextTagId = 0;
String get nextTag => 'x-type${nextTagId++}';

class NotAnElement {}

loadPolyfills() {
  if (!document.supportsRegister) {
    // Cache blocker is a workaround for:
    // https://code.google.com/p/dart/issues/detail?id=11834
    var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
    return HttpRequest.getString('/root_dart/pkg/custom_element/lib/'
      'custom-elements.debug.js?cacheBlock=$cacheBlocker').then((code) {
      document.head.children.add(new ScriptElement()..text = code);
    });
  }
}

main() {
  useHtmlIndividualConfiguration();

  setUp(loadPolyfills);

  group('register', () {
    test('register', () {
      var tag = nextTag;
      document.register(tag, CustomType);

      var element = new Element.tag(tag);
      expect(element, isNotNull);
      expect(element is CustomType, isTrue);
      expect(element.createdCalled, isTrue);
    });

    test('register twice', () {
      var tag = nextTag;
      document.register(tag, CustomType);
      expect(() {
        document.register(tag, CustomType);
      }, throws, reason: 'Cannot register a tag more than once.');

      var newTag = nextTag;
      document.register(newTag, CustomType);

      var element = new Element.tag(newTag);
      expect(element, isNotNull);
      expect(element is CustomType, isTrue);
    });

    test('register null', () {
      expect(() {
        document.register(nextTag, null);
      }, throws, reason: 'Cannot register a null type.');
    });

    test('register native', () {
      expect(() {
        document.register(nextTag, BodyElement);
      }, throws, reason: 'Cannot register a native element.');
    });

    test('register non-element', () {
      expect(() {
        document.register(nextTag, NotAnElement);
      }, throws, reason: 'Cannot register a non-element.');
    });
  });

  // TODO(vsm): Modify this test once we agree on the proper semantics.
  /*
  group('preregister', () {

    test('pre-registration construction', () {
      var tag = nextTag;
      var dom = new Element.html('<div><$tag></$tag></div>');

      var preElement = dom.children[0];
      expect(preElement, isNotNull);
      expect(preElement is HtmlElement, isTrue);
      expect(preElement is CustomType, isFalse);
      var firedOnPre = false;
      preElement.onFocus.listen((_) {
        firedOnPre = true;
      });

      document.register(tag, CustomType);
      upgradeCustomElements(dom);

      var postElement = dom.children[0];
      expect(postElement, isNotNull);
      expect(postElement is CustomType, isTrue);
      expect(postElement.createdCalled, isTrue);

      // Element from first query remains an UnknownElement.
      expect(preElement is HtmlElement, isTrue);
      expect(preElement.parent, dom);
      expect(dom.children.length, 1);

      var firedOnPost = false;
      postElement.onFocus.listen((_) {
        firedOnPost = true;
      });
      // Event handlers persist on old and new element.
      postElement.dispatchEvent(new Event('focus'));
      expect(firedOnPre, isTrue);
      expect(firedOnPost, isTrue);
    });
  });*/

  group('innerHtml', () {
    test('query', () {
      var tag = nextTag;
      document.register(tag, CustomType);
      var element = new DivElement();
      element.setInnerHtml('<$tag></$tag>',
          treeSanitizer: new NullTreeSanitizer());
	  upgradeCustomElements(element);
      document.body.nodes.add(element);
      var queried = query(tag);

      expect(queried, isNotNull);
      expect(queried is CustomType, isTrue);
      expect(queried.createdCalled, isTrue);
    });

    test('query id', () {
      var tag = nextTag;
      document.register(tag, CustomType);
      var element = new DivElement();
      element.setInnerHtml('<$tag id="someid"></$tag>',
          treeSanitizer: new NullTreeSanitizer());
	  upgradeCustomElements(element);
      document.body.nodes.add(element);
      var queried = query('#someid');

      expect(queried, isNotNull);
      expect(queried is CustomType, isTrue);
      expect(queried.id, "someid");
    });
  });

  group('lifecycle', () {
    test('created', () {
      int oldCount = customCreatedCount;
      var tag = nextTag;
      document.register(tag, CustomType);
      var element = new DivElement();
      element.setInnerHtml('<$tag></$tag>',
          treeSanitizer: new NullTreeSanitizer());
      upgradeCustomElements(element);
      document.body.nodes.add(element);
      expect(customCreatedCount, oldCount + 1);
    });
  });

  group('mixins', () {
    test('can invoke mixin methods', () {
      var tag = nextTag;
      document.register(tag, CustomType);

      var element = new Element.tag(tag);
      element.invokeMixinMethod();
      expect(element.mixinMethodCalled, isTrue);
    });
  });
}
