// Copyright (c) 2015, 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 source_map_name_test;

import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/io/source_information.dart';
import 'memory_compiler.dart';

const String SOURCE = '''

var toplevelField;
void toplevelMethod() {}
void toplevelAnonymous() {
  var foo = () {};
}
void toplevelLocal() {
  void localMethod() {}
}

class Class {
  Class() {
    var foo = () {};
  }
  Class.named() {
    void localMethod() {}
  }
  static var staticField;
  static staticMethod() {}
  static void staticAnonymous() {
    var foo = () {};
  }
  static void staticLocal() {
    void localMethod() {}
  }
  var instanceField;
  instanceMethod() {}
  void instanceAnonymous() {
    var foo = () {};
  }
  void instanceLocal() {
    void localMethod() {}
  }
  void instanceNestedLocal() {
    void localMethod() {
      var foo = () {};
      void nestedLocalMethod() {}
    }
  }
}

main() {
  toplevelField = toplevelMethod();
  toplevelAnonymous();
  toplevelLocal();

  Class.staticField = Class.staticMethod;
  Class.staticAnonymous();
  Class.staticLocal();

  var c = new Class();
  c = new Class.named();
  c.instanceField = c.instanceMethod();
  c.instanceAnonymous();
  c.instanceLocal();
  c.instanceNestedLocal();
}
''';

check(Element element, String expectedName) {
  String name = computeElementNameForSourceMaps(element);
  Expect.equals(expectedName, name,
      "Unexpected name '$name' for $element, expected '$expectedName'.");
}

main() {
  asyncTest(() async {
    CompilationResult result =
        await runCompiler(memorySourceFiles: {'main.dart': SOURCE});
    Compiler compiler = result.compiler;

    Element lookup(String name) {
      Element element;
      int dotPosition = name.indexOf('.');
      if (dotPosition != -1) {
        String clsName = name.substring(0, dotPosition);
        ClassElement cls = compiler.mainApp.find(clsName);
        Expect.isNotNull(cls, "Class '$clsName' not found.");
        element = cls.localLookup(name.substring(dotPosition + 1));
      } else {
        element = compiler.mainApp.find(name);
      }
      Expect.isNotNull(element, "Element '$name' not found.");
      return element;
    }

    void checkName(String expectedName,
        [List<String> expectedClosureNames, String lookupName]) {
      if (lookupName == null) {
        lookupName = expectedName;
      }
      var element = lookup(lookupName);
      check(element, expectedName);
      if (element.isConstructor) {
        var constructorBody =
            element.enclosingClass.lookupBackendMember(element.name);
        Expect.isNotNull(
            element, "Constructor body '${element.name}' not found.");
        check(constructorBody, expectedName);
      }

      if (expectedClosureNames != null) {
        int index = 0;
        for (var closure in element.nestedClosures) {
          String expectedName = expectedClosureNames[index];
          check(closure, expectedName);
          check(closure.expression, expectedName);
          check(closure.enclosingClass, expectedName);
          index++;
        }
      }
    }

    checkName('toplevelField');
    checkName('toplevelMethod');
    checkName('toplevelAnonymous', ['toplevelAnonymous.<anonymous function>']);
    checkName('toplevelLocal', ['toplevelLocal.localMethod']);
    checkName('Class');
    checkName('main');

    checkName('Class.staticField');
    checkName('Class.staticMethod');
    checkName('Class.staticAnonymous',
        ['Class.staticAnonymous.<anonymous function>']);
    checkName('Class.staticLocal', ['Class.staticLocal.localMethod']);

    checkName('Class', ['Class.<anonymous function>'], 'Class.');
    checkName('Class.named', ['Class.named.localMethod']);

    checkName('Class.instanceField');
    checkName('Class.instanceMethod');
    checkName('Class.instanceAnonymous',
        ['Class.instanceAnonymous.<anonymous function>']);
    checkName('Class.instanceLocal', ['Class.instanceLocal.localMethod']);
    checkName('Class.instanceNestedLocal', [
      'Class.instanceNestedLocal.localMethod',
      'Class.instanceNestedLocal.localMethod.<anonymous function>',
      'Class.instanceNestedLocal.localMethod.nestedLocalMethod'
    ]);
  });
}
