// Copyright (c) 2018, 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' show Directory, Platform, ProcessSignal, exit;

import 'package:analysis_server_client/handler/connection_handler.dart';
import 'package:analysis_server_client/handler/notification_handler.dart';
import 'package:analysis_server_client/protocol.dart';
import 'package:analysis_server_client/server.dart';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';

/// A simple application that uses the analysis server to analyze a package.
void main(List<String> args) async {
  var target = await parseArgs(args);
  print('Analyzing $target');

  // Launch the server
  var server = Server();
  await server.start();

  // Connect to the server
  var handler = _Handler(server);
  server.listenToOutput(notificationProcessor: handler.handleEvent);
  if (!await handler.serverConnected(timeLimit: const Duration(seconds: 15))) {
    exit(1);
  }

  // Request analysis
  await server.send(
    serverRequestSetSubscriptions,
    ServerSetSubscriptionsParams([ServerService.STATUS]).toJson(),
  );
  await server.send(
    analysisRequestSetAnalysisRoots,
    AnalysisSetAnalysisRootsParams([target], const []).toJson(),
  );

  // Continue to watch for analysis until the user presses Ctrl-C
  late StreamSubscription<ProcessSignal> subscription;
  subscription = ProcessSignal.sigint.watch().listen((_) async {
    print('Exiting...');
    // ignore: unawaited_futures
    subscription.cancel();
    await server.stop();
  });
}

Future<String> parseArgs(List<String> args) async {
  if (args.length != 1) {
    printUsageAndExit('Expected exactly one directory');
  }
  final dir = Directory(path.normalize(path.absolute(args[0])));
  if (!(await dir.exists())) {
    printUsageAndExit('Could not find directory ${dir.path}');
  }
  return dir.path;
}

void printUsageAndExit(String errorMessage) {
  print(errorMessage);
  print('');
  var appName = path.basename(Platform.script.toFilePath());
  print('Usage: $appName <directory path>');
  print('  Analyze the *.dart source files in <directory path>');
  exit(1);
}

class _Handler with NotificationHandler, ConnectionHandler {
  @override
  final Server server;
  int errorCount = 0;

  new(this.server);

  @override
  void onAnalysisErrors(AnalysisErrorsParams params) {
    var errors = params.errors;
    var first = true;
    for (var error in errors) {
      if (error.type.name == 'TODO') {
        // Ignore these types of "errors"
        continue;
      }
      if (first) {
        first = false;
        print('${params.file}:');
      }
      var loc = error.location;
      print('  ${error.message} • ${loc.startLine}:${loc.startColumn}');
      ++errorCount;
    }
  }

  @override
  void onFailedToConnect() {
    print('Failed to connect to server');
  }

  @override
  void onProtocolNotSupported(Version version) {
    print('Expected protocol version $PROTOCOL_VERSION, but found $version');
  }

  @override
  void onServerError(ServerErrorParams params) {
    if (params.isFatal) {
      print('Fatal Server Error: ${params.message}');
    } else {
      print('Server Error: ${params.message}');
    }
    print(params.stackTrace);
    super.onServerError(params);
  }

  @override
  void onServerStatus(ServerStatusParams params) {
    var analysisStatus = params.analysis;
    if (analysisStatus != null && !analysisStatus.isAnalyzing) {
      // Whenever the server stops analyzing,
      // print a brief summary of what issues have been found.
      if (errorCount == 0) {
        print('No issues found.');
      } else {
        print('Found $errorCount errors/warnings/hints');
      }
      errorCount = 0;
      print('--------- ctrl-c to exit ---------');
    }
  }
}
