// Copyright (c) 2014, 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 'dart:async';
import 'dart:io';

import 'package:args/args.dart';
import 'package:matcher/matcher.dart';
import 'package:path/path.dart' as path;

import 'fuzz/server_manager.dart';

/**
 * Start analysis server as a separate process and use the stdio to communicate
 * with the server.
 */
void main(List<String> args) {
  new _FuzzTest().run(args);
}

/**
 * Instances of [_FuzzTest] launch and test an analysis server.
 * You must specify the location of the Dart SDK and the directory
 * containing sources to be analyzed.
 */
class _FuzzTest {

  //TODO (danrubel) extract common behavior for use in multiple test scenarios
  //TODO (danrubel) cleanup test to use async/await for better readability
  // VM flag --enable_async

  static const String DART_SDK_OPTION = 'dart-sdk';
  static const String HELP_OPTION = 'help';

  File serverSnapshot;
  Directory appDir;

  /// Parse the arguments and initialize the receiver
  /// Return `true` if proper arguments were provided
  bool parseArgs(List<String> args) {
    ArgParser parser = new ArgParser();

    void error(String errMsg) {
      stderr.writeln(errMsg);
      print('');
      _printUsage(parser);
      exitCode = 11;
    }

    parser.addOption(DART_SDK_OPTION, help: '[sdkPath] path to Dart SDK');
    parser.addFlag(
        HELP_OPTION,
        help: 'print this help message without starting analysis',
        defaultsTo: false,
        negatable: false);

    ArgResults results;
    try {
      results = parser.parse(args);
    } on FormatException catch (e) {
      error(e.message);
      return false;
    }
    if (results[HELP_OPTION]) {
      _printUsage(parser);
      return false;
    }
    String sdkPath = results[DART_SDK_OPTION];
    if (sdkPath is! String) {
      error('Missing path to Dart SDK');
      return false;
    }
    Directory sdkDir = new Directory(sdkPath);
    if (!sdkDir.existsSync()) {
      error('Specified Dart SDK does not exist: $sdkPath');
      return false;
    }
    if (results.rest.length == 0) {
      error('Expected directory to analyze');
      return false;
    }
    appDir = new Directory(results.rest[0]);
    if (!appDir.existsSync()) {
      error('Specified application directory does not exist: $appDir');
      return false;
    }
    if (results.rest.length > 1) {
      error('Unexpected arguments after $appDir');
      return false;
    }
    serverSnapshot = new File(
        path.join(sdkDir.path, 'bin', 'snapshots', 'analysis_server.dart.snapshot'));
    if (!serverSnapshot.existsSync()) {
      error('Analysis Server snapshot not found: $serverSnapshot');
      return false;
    }
    return true;
  }

  /// Main entry point for launching, testing, and shutting down the server
  void run(List<String> args) {
    if (!parseArgs(args)) return;
    ServerManager.start(serverSnapshot.path).then((ServerManager manager) {
      runZoned(() {
        test(manager).then(manager.stop).then((_) {
          expect(manager.errorOccurred, isFalse);
          print('Test completed successfully');
        });
      }, onError: (error, stack) {
        stderr.writeln(error);
        print(stack);
        exitCode = 12;
        manager.stop();
      });
    });
  }

  /// Use manager to exercise the analysis server
  Future test(ServerManager manager) {

    // perform initial analysis
    return manager.analyze(appDir).then((AnalysisResults analysisResults) {
      print(
          'Found ${analysisResults.errorCount} errors,'
              ' ${analysisResults.warningCount} warnings,'
              ' and ${analysisResults.hintCount} hints in ${analysisResults.elapsed}');

      // edit a method body
      return manager.openFileNamed(
          'domain_completion.dart').then((Editor editor) {
        return editor.moveAfter('Response processRequest(Request request) {');
      }).then((Editor editor) {
        return editor.replace(0, '\nOb');
      }).then((Editor editor) {

        // request code completion and assert results
        return editor.getSuggestions().then((List<CompletionResults> list) {
          expect(list, isNotNull);
          expect(list.length, equals(0));
          list.forEach((CompletionResults results) {
            print('${results.elapsed} received ${results.suggestionCount} suggestions');
          });
          return editor;
        });

      }).then((Editor editor) {
        print('tests complete');
      });
    });
  }

  void _printAnalysisSummary(AnalysisResults results) {
    print(
        'Found ${results.errorCount} errors, ${results.warningCount} warnings,'
            ' and ${results.hintCount} hints in $results.elapsed');
  }

  /// Print information about how to use the server.
  void _printUsage(ArgParser parser) {
    print('Usage: analyzer [flags] <application_directory>');
    print('');
    print('Supported flags are:');
    print(parser.getUsage());
  }
}
