// 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:async_helper/async_helper.dart';
import 'package:compiler/src/constants/values.dart'
    show ConstantValue, StringConstantValue;
import 'package:expect/expect.dart';
import '../compiler_helper.dart';
import 'package:compiler/src/parser/partial_elements.dart'
    show PartialMetadataAnnotation;
import 'package:compiler/src/diagnostics/diagnostic_listener.dart'
    show DiagnosticReporter;

void checkPosition(Spannable spannable, Node node, String source,
    DiagnosticReporter reporter) {
  SourceSpan span = reporter.spanFromSpannable(spannable);
  Expect.isTrue(
      span.begin < span.end, 'begin = ${span.begin}; end = ${span.end}');
  Expect.isTrue(
      span.end < source.length, 'end = ${span.end}; length = ${source.length}');
  String yield = source.substring(span.begin, span.end);

  // TODO(ahe): The node does not include "@". Fix that.
  Expect.stringEquals('@$node', yield);
}

void checkAnnotation(String name, String declaration,
    {bool isTopLevelOnly: false}) {
  // Ensure that a compile-time constant can be resolved from an
  // annotation.
  var source1 = """const native = 'xyz';
                   @native
                   $declaration
                   main() {}""";

  analyzeAndCheck(source1, name, (compiler, element) {
    compiler.enqueuer.resolution.queueIsClosed = false;
    Expect.equals(
        1, element.metadata.length, 'Unexpected metadata count on $element.');
    PartialMetadataAnnotation annotation = element.metadata.first;
    annotation.ensureResolved(compiler.resolution);
    ConstantValue value =
        compiler.constants.getConstantValue(annotation.constant);
    Expect.isTrue(value is StringConstantValue);
    Expect.stringEquals('xyz', (value as StringConstantValue).stringValue);

    checkPosition(
        annotation, annotation.cachedNode, source1, compiler.reporter);
  });

  // Ensure that each repeated annotation has a unique instance of
  // [MetadataAnnotation].
  var source2 = """const native = 'xyz';
                   @native @native
                   $declaration
                   main() {}""";

  analyzeAndCheck(source2, name, (compiler, element) {
    compiler.enqueuer.resolution.queueIsClosed = false;
    Expect.equals(2, element.metadata.length);
    PartialMetadataAnnotation annotation1 = element.metadata.elementAt(0);
    PartialMetadataAnnotation annotation2 = element.metadata.elementAt(1);
    annotation1.ensureResolved(compiler.resolution);
    annotation2.ensureResolved(compiler.resolution);
    Expect.isFalse(
        identical(annotation1, annotation2), 'expected unique instances');
    Expect.notEquals(annotation1, annotation2, 'expected unequal instances');
    ConstantValue value1 =
        compiler.constants.getConstantValue(annotation1.constant);
    ConstantValue value2 =
        compiler.constants.getConstantValue(annotation2.constant);
    Expect.identical(value1, value2, 'expected same compile-time constant');
    Expect.isTrue(value1 is StringConstantValue);
    Expect.isTrue(value2 is StringConstantValue);
    Expect.stringEquals('xyz', (value1 as StringConstantValue).stringValue);
    Expect.stringEquals('xyz', (value2 as StringConstantValue).stringValue);

    checkPosition(
        annotation1, annotation1.cachedNode, source2, compiler.reporter);
    checkPosition(
        annotation2, annotation2.cachedNode, source2, compiler.reporter);
  });

  if (isTopLevelOnly) return;

  // Ensure that a compile-time constant can be resolved from an
  // annotation.
  var source3 = """const native = 'xyz';
                   class Foo {
                     @native
                     $declaration
                   }
                   main() {}""";

  analyzeAndCheck(source3, 'Foo', (compiler, dynamic element) {
    compiler.enqueuer.resolution.queueIsClosed = false;
    Expect.equals(0, element.metadata.length);
    element.ensureResolved(compiler.resolution);
    Expect.equals(0, element.metadata.length);
    element = element.lookupLocalMember(name);
    Expect.equals(1, element.metadata.length);
    PartialMetadataAnnotation annotation = element.metadata.first;
    annotation.ensureResolved(compiler.resolution);
    ConstantValue value =
        compiler.constants.getConstantValue(annotation.constant);
    Expect.isTrue(value is StringConstantValue);
    Expect.stringEquals('xyz', (value as StringConstantValue).stringValue);

    checkPosition(
        annotation, annotation.cachedNode, source3, compiler.reporter);
  });

  // Ensure that each repeated annotation has a unique instance of
  // [MetadataAnnotation].
  var source4 = """const native = 'xyz';
                   class Foo {
                     @native @native
                     $declaration
                   }
                   main() {}""";

  analyzeAndCheck(source4, 'Foo', (compiler, dynamic element) {
    compiler.enqueuer.resolution.queueIsClosed = false;
    Expect.equals(0, element.metadata.length);
    element.ensureResolved(compiler.resolution);
    Expect.equals(0, element.metadata.length);
    element = element.lookupLocalMember(name);
    Expect.equals(2, element.metadata.length);
    PartialMetadataAnnotation annotation1 = element.metadata.elementAt(0);
    PartialMetadataAnnotation annotation2 = element.metadata.elementAt(1);
    annotation1.ensureResolved(compiler.resolution);
    annotation2.ensureResolved(compiler.resolution);
    Expect.isFalse(
        identical(annotation1, annotation2), 'expected unique instances');
    Expect.notEquals(annotation1, annotation2, 'expected unequal instances');
    ConstantValue value1 =
        compiler.constants.getConstantValue(annotation1.constant);
    ConstantValue value2 =
        compiler.constants.getConstantValue(annotation2.constant);
    Expect.identical(value1, value2, 'expected same compile-time constant');
    Expect.isTrue(value1 is StringConstantValue);
    Expect.isTrue(value2 is StringConstantValue);
    Expect.stringEquals('xyz', (value1 as StringConstantValue).stringValue);
    Expect.stringEquals('xyz', (value2 as StringConstantValue).stringValue);

    checkPosition(
        annotation1, annotation1.cachedNode, source4, compiler.reporter);
    checkPosition(
        annotation1, annotation2.cachedNode, source4, compiler.reporter);
  });
}

void testClassMetadata() {
  checkAnnotation('Foo', 'class Foo {}', isTopLevelOnly: true);
}

void testTopLevelMethodMetadata() {
  checkAnnotation('foo', 'foo() {}');
}

void testTopLevelFieldMetadata() {
  checkAnnotation('foo', 'var foo;');
  checkAnnotation('bar', 'var foo, bar;');
}

void testLibraryTags() {
  void compileAndCheckLibrary(String source,
      List<MetadataAnnotation> extractMetadata(LibraryElement element)) {
    Uri partUri = new Uri(scheme: 'source', path: 'part.dart');
    String partSource = '@native part of foo;';

    Uri libUri = new Uri(scheme: 'source', path: 'lib.dart');
    String libSource = 'library lib;';

    Uri uri = new Uri(scheme: 'source', path: 'main.dart');

    var compiler = mockCompilerFor(source, uri, analyzeOnly: true)
      ..registerSource(partUri, partSource)
      ..registerSource(libUri, libSource);

    asyncTest(() => compiler.run(uri).then((_) {
          compiler.enqueuer.resolution.queueIsClosed = false;
          LibraryElement element = compiler.libraryLoader.lookupLibrary(uri);
          Expect.isNotNull(element, 'Cannot find $uri');

          List<MetadataAnnotation> metadata = extractMetadata(element);
          Expect.equals(1, metadata.length);

          PartialMetadataAnnotation annotation = metadata.first;
          annotation.ensureResolved(compiler.resolution);
          ConstantValue value =
              compiler.constants.getConstantValue(annotation.constant);
          Expect.isTrue(value is StringConstantValue);
          Expect.stringEquals(
              'xyz', (value as StringConstantValue).stringValue);

          checkPosition(
              annotation, annotation.cachedNode, source, compiler.reporter);
        }));
  }

  var source;

  source = """@native
              library foo;
              const native = 'xyz';
              main() {}""";
  compileAndCheckLibrary(source, (dynamic e) => e.libraryTag.metadata);

  source = """@native
              import 'lib.dart';
              const native = 'xyz';
              main() {}""";
  compileAndCheckLibrary(source, (dynamic e) => e.tags.single.metadata);

  source = """@native
              export 'lib.dart';
              const native = 'xyz';
              main() {}""";
  compileAndCheckLibrary(source, (dynamic e) => e.tags.single.metadata);

  source = """@native
              part 'part.dart';
              const native = 'xyz';
              main() {}""";
  compileAndCheckLibrary(source, (dynamic e) => e.tags.single.metadata);

  source = """@native
              part 'part.dart';
              const native = 'xyz';
              main() {}""";
  compileAndCheckLibrary(
      source, (dynamic e) => e.compilationUnits.first.partTag.metadata);
}

void main() {
  testClassMetadata();
  testTopLevelMethodMetadata();
  testTopLevelFieldMetadata();
  testLibraryTags();
}
