// Copyright (c) 2020, 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:path/path.dart' as path;

import '../core.dart';
import '../sdk.dart';
import '../utils.dart';
import 'analyze_impl.dart';

class AnalyzeCommand extends DartdevCommand<int> {
  AnalyzeCommand({bool verbose = false})
      : super('analyze', "Analyze the project's Dart code.") {
    argParser
      ..addFlag('fatal-infos',
          help: 'Treat info level issues as fatal.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('fatal-warnings',
          help: 'Treat warning level issues as fatal.',
          defaultsTo: true,
          negatable: true);
  }

  @override
  String get invocation => '${super.invocation} [<directory>]';

  @override
  FutureOr<int> run() async {
    if (argResults.rest.length > 1) {
      usageException('Only one directory is expected.');
    }

    // find directory from argResults.rest
    var dir = argResults.rest.isEmpty
        ? Directory.current
        : Directory(argResults.rest.single);
    if (!dir.existsSync()) {
      usageException("Directory doesn't exist: ${dir.path}");
    }

    final Completer<void> analysisCompleter = Completer<void>();
    final List<AnalysisError> errors = <AnalysisError>[];

    var progress = log.progress('Analyzing ${path.basename(dir.path)}');

    final AnalysisServer server = AnalysisServer(
      Directory(sdk.sdkPath),
      [dir],
    );

    StreamSubscription<bool> subscription;
    subscription = server.onAnalyzing.listen((bool isAnalyzing) {
      if (!isAnalyzing) {
        analysisCompleter.complete();
        subscription.cancel();
      }
    });
    server.onErrors.listen((FileAnalysisErrors fileErrors) {
      // Record the issues found (but filter out to do comments).
      errors.addAll(fileErrors.errors
          .where((AnalysisError error) => error.type != 'TODO'));
    });

    await server.start();
    // Completing the future in the callback can't fail.
    //ignore: unawaited_futures
    server.onExit.then<void>((int exitCode) {
      if (!analysisCompleter.isCompleted) {
        analysisCompleter.completeError('analysis server exited: $exitCode');
      }
    });

    await analysisCompleter.future;

    progress.finish(showTiming: true);

    errors.sort();

    if (errors.isNotEmpty) {
      final bullet = log.ansi.bullet;

      log.stdout('');

      bool hasErrors = false;
      bool hasWarnings = false;
      bool hasInfos = false;

      for (final AnalysisError error in errors) {
        // error • Message ... at path.dart:line:col • (code)

        var filePath = path.relative(error.file, from: dir.path);
        var severity = error.severity.toLowerCase().padLeft(7);
        if (error.isError) {
          severity = log.ansi.error(severity);
        }

        log.stdout(
          '$severity $bullet '
          '${log.ansi.emphasized(error.messageSentenceFragment)} '
          'at $filePath:${error.startLine}:${error.startColumn} $bullet '
          '(${error.code})',
        );

        hasErrors |= error.isError;
        hasWarnings |= error.isWarning;
        hasInfos |= error.isInfo;
      }

      log.stdout('');

      final errorCount = errors.length;
      log.stdout('$errorCount ${pluralize('issue', errorCount)} found.');

      // Return an error code in the range [0-3] dependent on the severity of
      // the issue(s) found.
      if (hasErrors) {
        return 3;
      }

      bool fatalWarnings = argResults['fatal-warnings'];
      bool fatalInfos = argResults['fatal-infos'];

      if (fatalWarnings && hasWarnings) {
        return 2;
      } else if (fatalInfos && hasInfos) {
        return 1;
      } else {
        return 0;
      }
    } else {
      log.stdout('No issues found!');
      return 0;
    }
  }
}
