// 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:expect/expect.dart";
import 'dart:async';
import "package:async_helper/async_helper.dart";
import 'mock_compiler.dart';
import '../../../sdk/lib/_internal/compiler/compiler.dart';
import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart' as leg;
import '../../../sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart';
import '../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart';
import '../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart';

const coreLib = r'''
library corelib;
class Object {
  Object();
}
class bool {}
class num {}
class int extends num {}
class double extends num {}
abstract class String {}
class Function {}
class List<T> {}
class Map<K,V> {}
class BoundClosure {}
class Closure {}
class Dynamic_ {}
class Null {}
class TypeError {}
class Type {}
class StackTrace {}
class LinkedHashMap {
  factory LinkedHashMap._empty() => null;
  factory LinkedHashMap._literal(elements) => null;
}
class Math {
  static double parseDouble(String s) => 1.0;
}
print(x) {}
identical(a, b) => true;
const proxy = 0;
''';

const ioLib = r'''
library io;
class Platform {
  static int operatingSystem;
}
''';

const htmlLib = r'''
library html;
Window __window;
Window get window => __window;
abstract class Window {
  Navigator get navigator;
}
abstract class Navigator {
  String get userAgent;
}
''';

const helperLib = r'''
library js_helper;
class JSInvocationMirror {}
assertHelper(a) {}
''';

const foreignLib = r'''
var JS;
''';

const isolateHelperLib = r'''
class _WorkerStub {
}
''';

testDart2Dart(String src, {void continuation(String s), bool minify: false,
    bool stripTypes: false}) {
  // If continuation is not provided, check that source string remains the same.
  if (continuation == null) {
    continuation = (s) { Expect.equals(src, s); };
  }
  testDart2DartWithLibrary(src, '', continuation: continuation, minify: minify,
      stripTypes: stripTypes);
}

/**
 * Library name is assumed to be 'mylib' in 'mylib.dart' file.
 */
testDart2DartWithLibrary(
    String srcMain, String srcLibrary,
    {void continuation(String s), bool minify: false,
    bool stripTypes: false}) {
  fileUri(path) => new Uri(scheme: 'file', path: path);

  final scriptUri = fileUri('script.dart');
  final libUri = fileUri('mylib.dart');

  provider(uri) {
    if (uri == scriptUri) return new Future.value(srcMain);
    if (uri.toString() == libUri.toString()) {
      return new Future.value(srcLibrary);
    }
    if (uri.path.endsWith('/core.dart')) {
      return new Future.value(coreLib);
    } else  if (uri.path.endsWith('/io.dart')) {
      return new Future.value(ioLib);
    } else if (uri.path.endsWith('/js_helper.dart')) {
      return new Future.value(helperLib);
    } else if (uri.path.endsWith('/html_dart2js.dart')) {
      // TODO(smok): The file should change to html_dartium at some point.
      return new Future.value(htmlLib);
    } else if (uri.path.endsWith('/foreign_helper.dart')) {
      return new Future.value(foreignLib);
    } else if (uri.path.endsWith('/isolate_helper.dart')) {
      return new Future.value(isolateHelperLib);
    }
    return new Future.value('');
  }

  handler(uri, begin, end, message, kind) {
    if (identical(kind, Diagnostic.ERROR) || identical(kind, Diagnostic.CRASH)) {
      Expect.fail('$uri: $begin-$end: $message [$kind]');
    }
  }

  final options = <String>['--output-type=dart'];
  // Some tests below are using dart:io.
  options.add('--categories=Client,Server');
  if (minify) options.add('--minify');
  if (stripTypes) options.add('--force-strip=types');

  asyncTest(() => compile(
      scriptUri,
      fileUri('libraryRoot/'),
      fileUri('packageRoot/'),
      provider,
      handler,
      options).then(continuation));
}

testSimpleFileUnparse() {
  final src = '''
should_be_dropped() {
}

should_be_kept() {
}

main() {
  should_be_kept();
}
''';
  testDart2Dart(src, continuation: (String s) {
    Expect.equals('should_be_kept(){}main(){should_be_kept();}', s);
  });
}

testTopLevelField() {
  testDart2Dart('final String x="asd";main(){x;}');
}

testSimpleTopLevelClass() {
  testDart2Dart('main(){new A();}class A{A(){}}');
}

testClassWithSynthesizedConstructor() {
  testDart2Dart('main(){new A();}class A{}');
}

testClassWithMethod() {
  testDart2Dart('main(){var a=new A();a.foo();}class A{void foo(){}}');
}

testExtendsImplements() {
  testDart2Dart('main(){new B<Object>();}'
      'class A<T>{}class B<T> extends A<T>{}');
}

testVariableDefinitions() {
  testDart2Dart('main(){var x,y;final String s=null;}',
      continuation: (String s) { Expect.equals('main(){}', s); });
  testDart2Dart('main(){final int x=0,y=0;final String s=null;}',
      continuation: (String s) { Expect.equals('main(){}', s); });
  testDart2Dart('foo(f,g){}main(){foo(1,2);}');
  testDart2Dart('foo(f(arg)){}main(){foo(main);}');
  // A couple of static/finals inside a class.
  testDart2Dart('main(){A.a;A.b;}class A{static const String a="5";'
      'static const String b="4";}');
  // Class member of typedef-ed function type.
  // Maybe typedef should be included in the result too, but it
  // works fine without it.
  testDart2Dart(
    'typedef void foofunc(arg);main(){new A((arg){});}'
    'class A{A(foofunc this.handler);final foofunc handler;}');
}

testGetSet() {
  // Top-level get/set.
  testDart2Dart('set foo(arg){}get foo{return 5;}main(){foo;foo=5;}');
  // Field get/set.
  testDart2Dart('main(){var a=new A();a.foo;a.foo=5;}'
      'class A{set foo(a){}get foo{return 5;}}');
  // Typed get/set.
  testDart2Dart('String get foo{return "a";}main(){foo;}');
}

testAbstractClass() {
  testDart2Dart('main(){A.foo;}abstract class A{final static num foo=0;}');
}

testConflictSendsRename() {
  // Various Send-s to current library and external library. Verify that
  // everything is renamed correctly in conflicting class names and global
  // functions.
  var librarySrc = '''
library mylib;

globalfoo() {}
var globalVar;
var globalVarInitialized = 6, globalVarInitialized2 = 7;

class A {
  A(){}
  A.fromFoo(){}
  static staticfoo(){}
  foo(){}
  static const field = 5;
}
''';
  var mainSrc = '''
import 'mylib.dart' as mylib;

globalfoo() {}
var globalVar;
var globalVarInitialized = 6, globalVarInitialized2 = 7;

class A {
  A(){}
  A.fromFoo(){}
  static staticfoo(){}
  foo(){}
  static const field = 5;
}

main() {
  globalVar;
  globalVarInitialized;
  globalVarInitialized2;
  globalfoo();
  A.field;
  A.staticfoo();
  new A();
  new A.fromFoo();
  new A().foo();

  mylib.globalVar;
  mylib.globalVarInitialized;
  mylib.globalVarInitialized2;
  mylib.globalfoo();
  mylib.A.field;
  mylib.A.staticfoo();
  new mylib.A();
  new mylib.A.fromFoo();
  new mylib.A().foo();
}
''';
  var expectedResult =
      'globalfoo(){}var globalVar;'
      'var globalVarInitialized=6;var globalVarInitialized2=7;'
      'class A{A(){}A.fromFoo(){}static staticfoo(){}foo(){}'
          'static const field=5;}'
      'A_globalfoo(){}'
      'var A_globalVar;var A_globalVarInitialized=6;'
          'var A_globalVarInitialized2=7;'
      'class A_A{A_A(){}A_A.A_fromFoo(){}static A_staticfoo(){}foo(){}'
          'static const A_field=5;}'
      'main(){A_globalVar;A_globalVarInitialized;'
         'A_globalVarInitialized2;A_globalfoo();'
         'A_A.A_field;A_A.A_staticfoo();'
         'new A_A();new A_A.A_fromFoo();new A_A().foo();'
         'globalVar;globalVarInitialized;globalVarInitialized2;globalfoo();'
         'A.field;A.staticfoo();'
         'new A();new A.fromFoo();new A().foo();}';
  testDart2DartWithLibrary(mainSrc, librarySrc,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testNoConflictSendsRename() {
  // Various Send-s to current library and external library. Nothing should be
  // renamed here, only library prefixes must be cut.
  var librarySrc = '''
library mylib;

globalfoo() {}

class A {
  A(){}
  A.fromFoo(){}
  static staticfoo(){}
  foo(){}
  static const field = 5;
}
''';
  var mainSrc = '''
import 'mylib.dart' as mylib;

myglobalfoo() {}

class MyA {
  MyA(){}
  MyA.myfromFoo(){}
  static mystaticfoo(){}
  myfoo(){}
  static const myfield = 5;
}

main() {
  myglobalfoo();
  MyA.myfield;
  MyA.mystaticfoo();
  new MyA();
  new MyA.myfromFoo();
  new MyA().myfoo();

  mylib.globalfoo();
  mylib.A.field;
  mylib.A.staticfoo();
  new mylib.A();
  new mylib.A.fromFoo();
  new mylib.A().foo();
}
''';
  var expectedResult =
      'globalfoo(){}'
      'class A{A(){}A.fromFoo(){}static staticfoo(){}foo(){}'
          'static const field=5;}'
      'myglobalfoo(){}'
      'class MyA{MyA(){}MyA.myfromFoo(){}static mystaticfoo(){}myfoo(){}'
          'static const myfield=5;}'
      'main(){myglobalfoo();MyA.myfield;MyA.mystaticfoo();new MyA();'
          'new MyA.myfromFoo();new MyA().myfoo();globalfoo();A.field;'
          'A.staticfoo();new A();new A.fromFoo();new A().foo();}';
  testDart2DartWithLibrary(mainSrc, librarySrc,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testConflictLibraryClassRename() {
  var librarySrc = '''
library mylib;

topfoo() {}

class A {
  foo(){}
}
''';
  var mainSrc = '''
import 'mylib.dart' as mylib;


topfoo() {var x = 5;}

class A{
  num foo() {}
  A.fromFoo() {}
  mylib.A myliba;
  List<A> mylist;
}

mylib.A getA() => null;

main() {
  var a = new mylib.A();
  a.foo();
  var b = new A.fromFoo();
  b.foo();
  var GREATVAR = b.myliba;
  b.mylist;
  a = getA();
  topfoo();
  mylib.topfoo();
}
''';
  var expectedResult =
    'topfoo(){}'
    'class A{foo(){}}'
    'A_topfoo(){}'
    'class A_A{num foo(){}A_A.fromFoo(){}A myliba;List<A_A> mylist;}'
    'A getA(){}'
    'main(){var a=new A();a.foo();var b=new A_A.fromFoo();b.foo();'
        'var GREATVAR=b.myliba;b.mylist;a=getA();A_topfoo();topfoo();}';
  testDart2DartWithLibrary(mainSrc, librarySrc,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testClassExtendsWithArgs() {
  testDart2Dart('main(){new B<Object>();}'
    'class A<T extends Object>{}'
    'class B<T extends Object> extends A<T>{}');
}

testStaticInvocation() {
  testDart2Dart('main(){var x=Math.parseDouble("1");}');
}

testLibraryGetSet() {
  var librarySrc = '''
library mylib;

get topgetset => 5;
set topgetset(arg) {}
''';
  var mainSrc = '''
import 'mylib.dart' as mylib;

get topgetset => 6;
set topgetset(arg) {}

main() {
  topgetset;
  topgetset = 6;

  mylib.topgetset;
  mylib.topgetset = 5;
}
''';
  var expectedResult =
    'get topgetset=>5;'
    'set topgetset(arg){}'
    'get A_topgetset=>6;'
    'set A_topgetset(arg){}'
    'main(){A_topgetset;A_topgetset=6;topgetset;topgetset=5;}';
  testDart2DartWithLibrary(mainSrc, librarySrc,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testFieldTypeOutput() {
  testDart2Dart('main(){new A().field;}class B{}class A{B field;}');
}

class DynoMap implements Map<Element, ElementAst> {
  final compiler;
  DynoMap(this.compiler);

  get resolvedElements => compiler.enqueuer.resolution.resolvedElements;
  ElementAst operator[](Element element) =>
      new ElementAst(element.parseNode(compiler), resolvedElements[element]);

  noSuchMethod(Invocation invocation) => throw 'unimplemented method';
}

PlaceholderCollector collectPlaceholders(compiler, element) =>
  new PlaceholderCollector(compiler, new Set<String>(), new DynoMap(compiler))
      ..collect(element);

testLocalFunctionPlaceholder() {
  var src = '''
main() {
  function localfoo() {}
  localfoo();
}
''';
  MockCompiler compiler = new MockCompiler(emitJavaScript: false);
  assert(compiler.backend is DartBackend);
  compiler.parseScript(src);
  FunctionElement mainElement = compiler.mainApp.find(leg.Compiler.MAIN);
  compiler.processQueue(compiler.enqueuer.resolution, mainElement);
  PlaceholderCollector collector = collectPlaceholders(compiler, mainElement);
  FunctionExpression mainNode = mainElement.parseNode(compiler);
  Block body = mainNode.body;
  FunctionDeclaration functionDeclaration = body.statements.nodes.head;
  FunctionExpression fooNode = functionDeclaration.function;
  LocalPlaceholder fooPlaceholder =
      collector.functionScopes[mainElement].localPlaceholders.first;
  Expect.isTrue(fooPlaceholder.nodes.contains(fooNode.name));
}

testTypeVariablesAreRenamed() {
  // Somewhat a hack: we require all the references of the identifier
  // to be renamed in the same way for the whole library. Hence
  // if we have a class and type variable with the same name, they
  // both should be renamed.
  var librarySrc = '''
library mylib;
typedef void MyFunction<T extends num>(T arg);
class T {}
class B<T> {}
class A<T> extends B<T> { T f; }
''';
  var mainSrc = '''
import 'mylib.dart' as mylib;
typedef void MyFunction<T extends num>(T arg);
class T {}
class B<T> {}
class A<T> extends B<T> { T f; }

main() {
  MyFunction myf1;
  mylib.MyFunction myf2;
  new A<int>().f;
  new T();

  new mylib.A<int>().f;
  new mylib.T();
}
''';
  var expectedResult =
    'typedef void MyFunction<T extends num>(T arg);'
    'class T{}'
    'class B<T>{}'
    'class A<T> extends B<T>{T f;}'
    'typedef void A_MyFunction<A_T extends num>(A_T arg);'
    'class A_T{}'
    'class A_B<A_T>{}'
    'class A_A<A_T> extends A_B<A_T>{A_T f;}'
    'main(){A_MyFunction myf1;MyFunction myf2;new A_A<int>().f;'
        'new A_T();new A<int>().f;new T();}';
  testDart2DartWithLibrary(mainSrc, librarySrc,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testClassTypeArgumentBound() {
  var librarySrc = '''
library mylib;

class I {}
class A<T extends I> {}

''';
  var mainSrc = '''
import 'mylib.dart' as mylib;

class I {}
class A<T extends I> {}

main() {
  new A();
  new mylib.A();
}
''';
  var expectedResult =
    'class I{}'
    'class A<T extends I>{}'
    'class A_I{}'
    'class A_A<A_T extends A_I>{}'
    'main(){new A_A();new A();}';
  testDart2DartWithLibrary(mainSrc, librarySrc,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testDoubleMains() {
  var librarySrc = '''
library mylib;
main() {}
''';
  var mainSrc = '''
import 'mylib.dart' as mylib;
main() {
  mylib.main();
}
''';
  var expectedResult =
    'A_main(){}'
    'main(){A_main();}';
  testDart2DartWithLibrary(mainSrc, librarySrc,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testStaticAccessIoLib() {
  var src = '''
import 'dart:io';

main() {
  Platform.operatingSystem;
}
''';
  var expectedResult = 'import "dart:io" as p;'
      'main(){p.Platform.operatingSystem;}';
  testDart2Dart(src,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testMinification() {
  var src = '''
class ClassWithVeryVeryLongName {}
main() {
  new ClassWithVeryVeryLongName();
}
''';
  var expectedResult =
      'class A{}'
      'main(){new A();}';
  testDart2Dart(src, continuation:
      (String result) { Expect.equals(expectedResult, result); }, minify: true);
}

testClosureLocalsMinified() {
  var src = '''
main() {
  var a = 7;
  void foo1(a,b) {
    void foo2(c,d) {
       var E = a;
    }
    foo2(b, a);
  }
  foo1(a, 8);
}
''';
  var expectedResult =
      'main(){var A=7; B(A,C){ D(E,F){var G=A;}D(C,A);}B(A,8);}';
  testDart2Dart(src, continuation:
      (String result) { Expect.equals(expectedResult, result); }, minify: true);
}

testParametersMinified() {
  var src = '''
class A {
  var a;
  static foo(arg1) {
    // Should not rename arg1 to a.
    arg1 = 5;
  }
}

fooglobal(arg,{optionalarg: 7}) {
  arg = 6;
}

main() {
  new A().a;
  A.foo(8);
  fooglobal(8);
}
''';
  var expectedResult =
      'class B{var E;static C(A){A=5;}}D(A,{optionalarg: 7}){A=6;}'
      'main(){new B().E;B.C(8);D(8);}';
  testDart2Dart(src, continuation:
      (String result) { Expect.equals(expectedResult, result); }, minify: true);
}

testDeclarationTypePlaceholders() {
  var src = '''
String globalfield;
const String globalconstfield;

void foo(String arg) {}

main() {
  String localvar;
  foo("5");
}
''';
  var expectedResult =
      ' foo( arg){}main(){var localvar;foo("5");}';
  testDart2Dart(src,
      continuation: (String result) { Expect.equals(expectedResult, result); },
      stripTypes: true);
}

testPlatformLibraryMemberNamesAreFixed() {
  var src = '''
import 'dart:html';

class A {
  static String get userAgent => window.navigator.userAgent;
}

main() {
  A.userAgent;
}
''';
  var expectedResult = 'import "dart:html" as p;'
      'class A{static String get A_userAgent=>p.window.navigator.userAgent;}'
      'main(){A.A_userAgent;}';
  testDart2Dart(src,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testConflictsWithCoreLib() {
  var src = '''
import 'dart:core' as fisk;

print(x) { throw 'fisk'; }

main() {
  fisk.print('corelib');
  print('local');
}
''';
  var expectedResult = "A_print(x){throw 'fisk';}"
      "main(){print('corelib');A_print('local');}";
  testDart2Dart(src,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

testUnresolvedNamedConstructor() {
  var src = '''
class A {
  A() {}
}

main() {
  new A();
  new A.named();
}
''';
  var expectedResult = "class A{A(){}}main(){new A();new A_Unresolved();}";
  testDart2Dart(src,
      continuation: (String result) { Expect.equals(expectedResult, result); });
}

main() {
  testSimpleFileUnparse();
  testTopLevelField();
  testSimpleTopLevelClass();
  testClassWithSynthesizedConstructor();
  testClassWithMethod();
  testExtendsImplements();
  testVariableDefinitions();
  testGetSet();
  testAbstractClass();
  testConflictSendsRename();
  testNoConflictSendsRename();
  testConflictLibraryClassRename();
  testClassExtendsWithArgs();
  testStaticInvocation();
  testLibraryGetSet();
  testFieldTypeOutput();
  testTypeVariablesAreRenamed();
  testClassTypeArgumentBound();
  testDoubleMains();
  testStaticAccessIoLib();
  testLocalFunctionPlaceholder();
  testMinification();
  testClosureLocalsMinified();
  testParametersMinified();
  testDeclarationTypePlaceholders();
  testPlatformLibraryMemberNamesAreFixed();
  testConflictsWithCoreLib();
  testUnresolvedNamedConstructor();
}
