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

// Test the exit code of dart2js in case of exceptions, errors, warnings, etc.


import 'dart:async';
import 'dart:io' show Platform;

import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';

import 'package:compiler/compiler.dart' as api;
import 'package:compiler/src/dart2js.dart' as entry;
import 'package:compiler/src/dart2jslib.dart';
import 'package:compiler/src/apiimpl.dart' as apiimpl;
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/library_loader.dart';
import 'package:compiler/src/resolution/resolution.dart';
import 'package:compiler/src/scanner/scannerlib.dart';
import 'package:compiler/src/util/util.dart';

class TestCompiler extends apiimpl.Compiler {
  final String testMarker;
  final String testType;
  final Function onTest;

  TestCompiler(api.CompilerInputProvider inputProvider,
                api.CompilerOutputProvider outputProvider,
                api.DiagnosticHandler handler,
                Uri libraryRoot,
                Uri packageRoot,
                List<String> options,
                Map<String, dynamic> environment,
                String this.testMarker,
                String this.testType,
                Function this.onTest)
      : super(inputProvider, outputProvider, handler, libraryRoot,
              packageRoot, options, environment) {
    scanner = new TestScanner(this);
    resolver = new TestResolver(this, backend.constantCompilerTask);
    test('Compiler');
  }

  Future<bool> run(Uri uri) {
    test('Compiler.run');
    return super.run(uri);
  }

  Future onLibraryScanned(LibraryElement element, LibraryLoader loader) {
    test('Compiler.onLibraryScanned');
    return super.onLibraryScanned(element, loader);
  }

  Future onLibrariesLoaded(LoadedLibraries loadedLibraries) {
    test('Compiler.onLibrariesLoaded');
    return super.onLibrariesLoaded(loadedLibraries);
  }

  void analyzeElement(Element element) {
    test('Compiler.analyzeElement');
    super.analyzeElement(element);
  }

  void codegen(CodegenWorkItem work, CodegenEnqueuer world) {
    test('Compiler.codegen');
    super.codegen(work, world);
  }

  withCurrentElement(Element element, f()) {
    return super.withCurrentElement(element, () {
      test('Compiler.withCurrentElement');
      return f();
    });
  }

  test(String marker) {
    if (marker == testMarker) {
      switch (testType) {
      case 'assert':
        onTest(testMarker, testType);
        assert(false);
        break;
      case 'invariant':
        onTest(testMarker, testType);
        invariant(NO_LOCATION_SPANNABLE, false, message: marker);
        break;
      case 'warning':
        onTest(testMarker, testType);
        reportWarning(NO_LOCATION_SPANNABLE,
                      MessageKind.GENERIC, {'text': marker});
        break;
      case 'error':
        onTest(testMarker, testType);
        reportError(NO_LOCATION_SPANNABLE,
                    MessageKind.GENERIC, {'text': marker});
        break;
      case 'internalError':
        onTest(testMarker, testType);
        internalError(NO_LOCATION_SPANNABLE, marker);
        break;
      case 'NoSuchMethodError':
        onTest(testMarker, testType);
        null.foo;
        break;
      case '':
        onTest(testMarker, testType);
        break;
      }
    }
  }
}

class TestScanner extends ScannerTask {
  TestScanner(TestCompiler compiler) : super(compiler);

  TestCompiler get compiler => super.compiler;

  void scanElements(CompilationUnitElement compilationUnit) {
    compiler.test('ScannerTask.scanElements');
    super.scanElements(compilationUnit);
  }
}

class TestResolver extends ResolverTask {
  TestResolver(TestCompiler compiler, ConstantCompiler constantCompiler)
      : super(compiler, constantCompiler);

  TestCompiler get compiler => super.compiler;

  void computeClassMembers(ClassElement element) {
    compiler.test('ResolverTask.computeClassMembers');
    super.computeClassMembers(element);
  }
}

int checkedResults = 0;

Future testExitCode(String marker, String type, int expectedExitCode) {
  bool testOccurred = false;

  void onTest(String testMarker, String testType) {
    if (testMarker == marker && testType == type) {
      testOccurred = true;
    }
  }
  return new Future(() {
    Future<api.CompilationResult> compile(
        Uri script,
        Uri libraryRoot,
        Uri packageRoot,
        api.CompilerInputProvider inputProvider,
        api.DiagnosticHandler handler,
        [List<String> options = const [],
         api.CompilerOutputProvider outputProvider,
         Map<String, dynamic> environment = const {}]) {
      libraryRoot = Platform.script.resolve('../../../sdk/');
      outputProvider = NullSink.outputProvider;
      // Use this to silence the test when debugging:
      // handler = (uri, begin, end, message, kind) {};
      Compiler compiler = new TestCompiler(inputProvider,
                                           outputProvider,
                                           handler,
                                           libraryRoot,
                                           packageRoot,
                                           options,
                                           environment,
                                           marker,
                                           type,
                                           onTest);
      return compiler.run(script).then((bool success) {
        return new api.CompilationResult(compiler, isSuccess: success);
      });
    }

    int foundExitCode;

    checkResult() {
      Expect.isTrue(testOccurred, 'testExitCode($marker, $type) did not occur');
      if (foundExitCode == null) foundExitCode = 0;
      print('testExitCode($marker, $type) '
            'exitCode=$foundExitCode expected=$expectedExitCode');
      Expect.equals(expectedExitCode, foundExitCode,
          'testExitCode($marker, $type) '
          'exitCode=$foundExitCode expected=${expectedExitCode}');
      checkedResults++;
    }

    void exit(exitCode) {
      if (foundExitCode == null) {
        foundExitCode = exitCode;
      }
    };

    entry.exitFunc = exit;
    entry.compileFunc = compile;

    Future result = entry.internalMain(
        ["tests/compiler/dart2js/exit_code_helper.dart"]);
    return result.catchError((e, s) {
      // Capture crashes.
    }).whenComplete(checkResult);
  });
}

Future testExitCodes(String marker, Map<String,int> expectedExitCodes) {
  return Future.forEach(expectedExitCodes.keys, (String type) {
    return testExitCode(marker, type, expectedExitCodes[type]);
  });
}

void main() {
  bool isCheckedMode = false;
  assert((isCheckedMode = true));

  final beforeRun = {
    '': 0,
    'NoSuchMethodError': 253,
    'assert': isCheckedMode ? 253 : 0,
    'invariant': 253
  };

  final duringRun = {
    '': 0,
    'NoSuchMethodError': 253,
    'assert': isCheckedMode ? 253 : 0,
    'invariant': 253,
    'warning': 0,
    'error': 1,
    'internalError': 253,
  };

  final tests = {
    'Compiler': beforeRun,
    'Compiler.run': beforeRun,
    'Compiler.onLibraryScanned': beforeRun,
    'Compiler.onLibrariesLoaded': beforeRun,
    'ScannerTask.scanElements': duringRun,
    'Compiler.withCurrentElement': duringRun,
    'Compiler.analyzeElement': duringRun,
    'Compiler.codegen': duringRun,
    'ResolverTask.computeClassMembers': duringRun,
  };

  asyncStart();
  Future.forEach(tests.keys, (marker) {
    return testExitCodes(marker, tests[marker]);
  }).then((_) {
    int countResults(Map runType) {
      return runType.length *
             tests.values.where((r) => r == runType).length;
    }

    Expect.equals(countResults(beforeRun) + countResults(duringRun),
                  checkedResults);
    asyncEnd();
  });
}
