// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:meta/meta.dart';
import 'package:process/process.dart';

import '../artifacts.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../base/terminal.dart';
import '../project_validator.dart';
import '../runner/flutter_command.dart';
import 'analyze_base.dart';
import 'analyze_continuously.dart';
import 'analyze_once.dart';
import 'validate_project.dart';

class AnalyzeCommand extends FlutterCommand {
  AnalyzeCommand({
    bool verboseHelp = false,
    this.workingDirectory,
    required FileSystem fileSystem,
    required Platform platform,
    required Terminal terminal,
    required Logger logger,
    required ProcessManager processManager,
    required Artifacts artifacts,
    required List<ProjectValidator> allProjectValidators,
  }) : _artifacts = artifacts,
       _fileSystem = fileSystem,
       _processManager = processManager,
       _logger = logger,
       _terminal = terminal,
       _allProjectValidators = allProjectValidators,
       _platform = platform {
    argParser.addFlag('flutter-repo',
        negatable: false,
        help: 'Include all the examples and tests from the Flutter repository.',
        hide: !verboseHelp);
    argParser.addFlag('current-package',
        help: 'Analyze the current project, if applicable.', defaultsTo: true);
    argParser.addFlag('dartdocs',
        negatable: false,
        help: '(deprecated) List every public member that is lacking documentation. '
              'This command will be removed in a future version of Flutter.',
        hide: !verboseHelp);
    argParser.addFlag('watch',
        help: 'Run analysis continuously, watching the filesystem for changes.',
        negatable: false);
    argParser.addOption('write',
        valueHelp: 'file',
        help: 'Also output the results to a file. This is useful with "--watch" '
              'if you want a file to always contain the latest results.');
    argParser.addOption('dart-sdk',
        valueHelp: 'path-to-sdk',
        help: 'The path to the Dart SDK.',
        hide: !verboseHelp);
    argParser.addOption('protocol-traffic-log',
        valueHelp: 'path-to-protocol-traffic-log',
        help: 'The path to write the request and response protocol. This is '
              'only intended to be used for debugging the tooling.',
        hide: !verboseHelp);
    argParser.addFlag('suggestions',
        help: 'Show suggestions about the current flutter project.'
    );

    // Hidden option to enable a benchmarking mode.
    argParser.addFlag('benchmark',
        negatable: false,
        hide: !verboseHelp,
        help: 'Also output the analysis time.');

    usesPubOption();

    // Not used by analyze --watch
    argParser.addFlag('congratulate',
        help: 'Show output even when there are no errors, warnings, hints, or lints. '
              'Ignored if "--watch" is specified.',
        defaultsTo: true);
    argParser.addFlag('preamble',
        defaultsTo: true,
        help: 'When analyzing the flutter repository, display the number of '
              'files that will be analyzed.\n'
              'Ignored if "--watch" is specified.');
    argParser.addFlag('fatal-infos',
        help: 'Treat info level issues as fatal.',
        defaultsTo: true);
    argParser.addFlag('fatal-warnings',
        help: 'Treat warning level issues as fatal.',
        defaultsTo: true);
  }

  /// The working directory for testing analysis using dartanalyzer.
  final Directory? workingDirectory;

  final Artifacts _artifacts;
  final FileSystem _fileSystem;
  final Logger _logger;
  final Terminal _terminal;
  final ProcessManager _processManager;
  final Platform _platform;
  final List<ProjectValidator> _allProjectValidators;

  @override
  String get name => 'analyze';

  @override
  String get description => "Analyze the project's Dart code.";

  @override
  String get category => FlutterCommandCategory.project;

  @visibleForTesting
  List<ProjectValidator> allProjectValidators() => _allProjectValidators;

  @override
  bool get shouldRunPub {
    // If they're not analyzing the current project.
    if (!boolArgDeprecated('current-package')) {
      return false;
    }

    // Or we're not in a project directory.
    if (!_fileSystem.file('pubspec.yaml').existsSync()) {
      return false;
    }

    return super.shouldRunPub;
  }

  @override
  Future<FlutterCommandResult> runCommand() async {
    final bool? suggestionFlag = boolArg('suggestions');
    if (suggestionFlag != null && suggestionFlag == true) {
      final String directoryPath;
      final bool? watchFlag = boolArg('watch');
      if (watchFlag != null && watchFlag) {
        throwToolExit('flag --watch is not compatible with --suggestions');
      }
      if (workingDirectory == null) {
        final Set<String> items = findDirectories(argResults!, _fileSystem);
        if (items.isEmpty) { // user did not specify any path
          directoryPath = _fileSystem.currentDirectory.path;
          _logger.printTrace('Showing suggestions for current directory: $directoryPath');
        } else if (items.length > 1) { // if the user sends more than one path
          throwToolExit('The suggestions flag can process only one directory path');
        } else {
          directoryPath = items.first;
        }
      } else {
        directoryPath = workingDirectory!.path;
      }
      return ValidateProject(
        fileSystem: _fileSystem,
        logger: _logger,
        allProjectValidators: _allProjectValidators,
        userPath: directoryPath,
        processManager: _processManager,
      ).run();
    } else if (boolArgDeprecated('watch')) {
      await AnalyzeContinuously(
        argResults!,
        runner!.getRepoRoots(),
        runner!.getRepoPackages(),
        fileSystem: _fileSystem,
        logger: _logger,
        platform: _platform,
        processManager: _processManager,
        terminal: _terminal,
        artifacts: _artifacts,
      ).analyze();
    } else {
      await AnalyzeOnce(
        argResults!,
        runner!.getRepoRoots(),
        runner!.getRepoPackages(),
        workingDirectory: workingDirectory,
        fileSystem: _fileSystem,
        logger: _logger,
        platform: _platform,
        processManager: _processManager,
        terminal: _terminal,
        artifacts: _artifacts,
      ).analyze();
    }
    return FlutterCommandResult.success();
  }
}
