// 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.

// Test of "recursive" imports using the dart2js compiler API.

import "package:expect/expect.dart";
import 'dart:async';
import '../../sdk/lib/_internal/compiler/compiler.dart';

const CORE_LIB = """
library core;
class Object {
  Object();
  operator==(other) {}
}
class bool {}
class num {}
class int {}
class double{}
class String{}
class Function{}
class List {}
class Map {}
class BoundClosure {}
class Closure {}
class Dynamic_ {}
class Type {}
class Null {}
class StackTrace {}
class LinkedHashMap {}
getRuntimeTypeInfo(o) {}
setRuntimeTypeInfo(o, i) {}
eqNull(a) {}
eqNullB(a) {}
class JSInvocationMirror {}  // Should be in helper.
""";

const INTERCEPTORS_LIB = """
library interceptors;
class JSIndexable {
  get length;
}
class JSMutableIndexable {}
class JSArray {
  removeLast() => null;
  add(x) { }
}
class JSMutableArray extends JSArray {}
class JSExtendableArray extends JSMutableArray {}
class JSFixedArray extends JSMutableArray {}
class JSString {
  split(x) => null;
  concat(x) => null;
  toString() => null;
}
class JSNull {
}
class JSBool {
}
""";

const String RECURSIVE_MAIN = """
library fisk;
import 'recurse/fisk.dart';
main() {}
""";


main() {
  int count = 0;
  Future<String> provider(Uri uri) {
    String source;
    if (uri.path.length > 100) {
      // Simulate an OS error.
      throw 'Path length exceeded';
    } else if (uri.scheme == "main") {
      count++;
      source = RECURSIVE_MAIN;
    } else if (uri.scheme == "lib") {
      if (uri.path.endsWith("/core.dart")) {
        source = CORE_LIB;
      } else if (uri.path.endsWith('_patch.dart')) {
        source = '';
      } else if (uri.path.endsWith('isolate_helper.dart')) {
        source = 'class _WorkerStub {}';
      } else if (uri.path.endsWith('interceptors.dart')) {
        source = INTERCEPTORS_LIB;
      } else {
        source = "library lib${uri.path.replaceAll('/', '.')};";
      }
    } else {
     throw "unexpected URI $uri";
    }
    return new Future.value(source);
  }

  int warningCount = 0;
  int errorCount = 0;
  void handler(Uri uri, int begin, int end, String message, Diagnostic kind) {
    if (uri != null) {
      // print('$uri:$begin:$end: $kind: $message');
      Expect.equals('main', uri.scheme);
      if (kind == Diagnostic.WARNING) {
        warningCount++;
      } else if (kind == Diagnostic.ERROR) {
        errorCount++;
      } else {
        throw kind;
      }
    }
  }

  Future<String> result =
      compile(new Uri(scheme: 'main'),
              new Uri(scheme: 'lib', path: '/'),
              new Uri(scheme: 'package', path: '/'),
              provider, handler);
  result.then((String code) {
    Expect.isNull(code);
    Expect.isTrue(10 < count);
    // Two warnings for each time RECURSIVE_MAIN is read, except the
    // first time.
    Expect.equals(2 * (count - 1), warningCount);
    Expect.equals(1, errorCount);
  }, onError: (e) {
      throw 'Compilation failed';
  });
}
