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

import 'dart:io' as io;

import 'package:file/file.dart';

import 'common/core.dart';
import 'common/file_filters.dart';
import 'common/flutter_command_utils.dart';
import 'common/gradle.dart';
import 'common/output_utils.dart';
import 'common/package_looping_command.dart';
import 'common/plugin_utils.dart';
import 'common/repository_package.dart';
import 'common/xcode.dart';

/// A command to run Dart analysis on packages.
class AnalyzeCommand extends PackageLoopingCommand {
  /// Creates a analysis command instance.
  AnalyzeCommand(
    super.packagesDir, {
    super.processRunner,
    super.platform,
    super.gitDir,
  }) {
    // Platform options.
    // By default, only Dart analysis is run.
    argParser.addFlag(_dartFlag, help: "Runs 'dart analyze'", defaultsTo: true);
    argParser.addFlag(platformAndroid,
        help: "Runs 'gradle lint' on Android code");
    argParser.addFlag(platformIOS,
        help: "Runs 'xcodebuild analyze' on iOS code");
    argParser.addFlag(platformMacOS,
        help: "Runs 'xcodebuild analyze' on macOS code");

    // Dart options.
    argParser.addMultiOption(_customAnalysisFlag,
        help:
            'Directories (comma separated) that are allowed to have their own '
            'analysis options.\n\n'
            'Alternately, a list of one or more YAML files that contain a list '
            'of allowed directories.',
        defaultsTo: <String>[]);
    argParser.addOption(_analysisSdk,
        valueHelp: 'dart-sdk',
        help: 'An optional path to a Dart SDK; this is used to override the '
            'SDK used to provide analysis.');
    argParser.addFlag(_downgradeFlag,
        help: 'Runs "flutter pub downgrade" before analysis to verify that '
            'the minimum constraints are sufficiently new for APIs used.');
    argParser.addFlag(_libOnlyFlag,
        help: 'Only analyze the lib/ directory of the main package, not the '
            'entire package.');
    argParser.addFlag(_skipIfResolvingFailsFlag,
        help: 'If resolution fails, skip the package. This is only '
            'intended to be used with pathified analysis, where a resolver '
            'failure indicates that no out-of-band failure can result anyway.',
        hide: true);

    // Xcode options.
    argParser.addOption(_minIOSVersionArg,
        help: 'Sets the minimum iOS deployment version to use when compiling, '
            'overriding the default minimum version. This can be used to find '
            'deprecation warnings that will affect the plugin in the future.');
    argParser.addOption(_minMacOSVersionArg,
        help:
            'Sets the minimum macOS deployment version to use when compiling, '
            'overriding the default minimum version. This can be used to find '
            'deprecation warnings that will affect the plugin in the future.');
  }

  static const String _dartFlag = 'dart';
  static const String _customAnalysisFlag = 'custom-analysis';
  static const String _downgradeFlag = 'downgrade';
  static const String _libOnlyFlag = 'lib-only';
  static const String _analysisSdk = 'analysis-sdk';
  static const String _skipIfResolvingFailsFlag = 'skip-if-resolving-fails';
  static const String _minIOSVersionArg = 'ios-min-version';
  static const String _minMacOSVersionArg = 'macos-min-version';

  late String _dartBinaryPath;

  Set<String> _allowedCustomAnalysisDirectories = const <String>{};

  @override
  final String name = 'analyze';

  @override
  final String description = 'Analyzes all packages using dart analyze.\n\n'
      'This command requires "dart" and "flutter" to be in your path.';

  /// Checks that there are no unexpected analysis_options.yaml files.
  bool _hasUnexpectedAnalysisOptions(RepositoryPackage package) {
    final List<FileSystemEntity> files =
        package.directory.listSync(recursive: true, followLinks: false);
    for (final FileSystemEntity file in files) {
      if (file.basename != 'analysis_options.yaml' &&
          file.basename != '.analysis_options') {
        continue;
      }

      final bool allowed = _allowedCustomAnalysisDirectories.any(
          (String directory) =>
              directory.isNotEmpty &&
              path.isWithin(
                  packagesDir.childDirectory(directory).path, file.path));
      if (allowed) {
        continue;
      }

      printError(
          'Found an extra analysis_options.yaml at ${file.absolute.path}.');
      printError(
          'If this was deliberate, pass the package to the analyze command '
          'with the --$_customAnalysisFlag flag and try again.');
      return true;
    }
    return false;
  }

  @override
  bool shouldIgnoreFile(String path) {
    // Support files don't affect any analysis.
    if (isRepoLevelNonCodeImpactingFile(path) || isPackageSupportFile(path)) {
      return true;
    }

    // For native code, it depends on the flags.
    if (path.endsWith('.dart')) {
      return !getBoolArg(_dartFlag);
    }
    if (path.endsWith('.java') || path.endsWith('.kt')) {
      return !getBoolArg(platformAndroid);
    }
    if (path.endsWith('.c') ||
        path.endsWith('.cc') ||
        path.endsWith('.cpp') ||
        path.endsWith('.h')) {
      // If C/C++ linting is added, Windows and Linux should be added here.
      return !(getBoolArg(platformIOS) || getBoolArg(platformMacOS));
    }
    if (path.endsWith('.m') ||
        path.endsWith('.mm') ||
        path.endsWith('.swift')) {
      return !(getBoolArg(platformIOS) || getBoolArg(platformMacOS));
    }

    return false;
  }

  @override
  Future<void> initializeRun() async {
    _allowedCustomAnalysisDirectories = getYamlListArg(_customAnalysisFlag);

    // Use the Dart SDK override if one was passed in.
    final String? dartSdk = argResults![_analysisSdk] as String?;
    _dartBinaryPath =
        dartSdk == null ? 'dart' : path.join(dartSdk, 'bin', 'dart');
  }

  @override
  Future<PackageResult> runForPackage(RepositoryPackage package) async {
    final Map<String, PackageResult> subResults = <String, PackageResult>{};
    if (getBoolArg(_dartFlag)) {
      _printSectionHeading('Running dart analyze.');
      subResults['Dart'] = await _runDartAnalysisForPackage(package);
    }
    if (getBoolArg(platformAndroid)) {
      _printSectionHeading('Running gradle lint.');
      subResults['Android'] = await _runGradleLintForPackage(package);
    }
    if (getBoolArg(platformIOS)) {
      _printSectionHeading('Running iOS xcodebuild analyze.');
      final String minIOSVersion = getStringArg(_minIOSVersionArg);
      subResults['iOS'] = await _runXcodeAnalysisForPackage(
        package,
        FlutterPlatform.ios,
        extraFlags: <String>[
          '-destination',
          'generic/platform=iOS Simulator',
          if (minIOSVersion.isNotEmpty)
            'IPHONEOS_DEPLOYMENT_TARGET=$minIOSVersion',
        ],
      );
    }
    if (getBoolArg(platformMacOS)) {
      _printSectionHeading('Running macOS xcodebuild analyze.');
      final String minMacOSVersion = getStringArg(_minMacOSVersionArg);
      subResults['macOS'] = await _runXcodeAnalysisForPackage(
        package,
        FlutterPlatform.macos,
        extraFlags: <String>[
          if (minMacOSVersion.isNotEmpty)
            'MACOSX_DEPLOYMENT_TARGET=$minMacOSVersion',
        ],
      );
    }

    // Make sure at least one analysis option was requested.
    if (subResults.isEmpty) {
      printError('At least one analysis option flag must be provided.');
      throw ToolExit(exitInvalidArguments);
    }
    // If only one analysis was requested, just return its result.
    if (subResults.length == 1) {
      return subResults.values.first;
    }
    // Otherwise, aggregate the messages, with the least positive status.
    final Map<String, PackageResult> failedResults =
        Map<String, PackageResult>.of(subResults)
          ..removeWhere((String key, PackageResult value) =>
              value.state != RunState.failed);
    final Map<String, PackageResult> skippedResults =
        Map<String, PackageResult>.of(subResults)
          ..removeWhere((String key, PackageResult value) =>
              value.state != RunState.skipped);
    // If anything failed, collect all the failure messages, prefixed by type.
    if (failedResults.isNotEmpty) {
      return PackageResult.fail(<String>[
        for (final MapEntry<String, PackageResult> entry
            in failedResults.entries)
          '${entry.key}${entry.value.details.isEmpty ? '' : ': ${entry.value.details.join(', ')}'}'
      ]);
    }
    // If everything was skipped, mark as skipped with all of the explanations.
    if (skippedResults.length == subResults.length) {
      return PackageResult.skip(skippedResults.entries
          .map((MapEntry<String, PackageResult> entry) =>
              '${entry.key}: ${entry.value.details.first}')
          .join(', '));
    }
    // For all succes, or a mix of success and skip, log any skips but mark as
    // success.
    for (final MapEntry<String, PackageResult> skip in skippedResults.entries) {
      printSkip('Skipped ${skip.key}: ${skip.value.details.first}');
    }
    return PackageResult.success();
  }

  void _printSectionHeading(String heading) {
    print('\n$heading');
    print('--------------------');
  }

  /// Runs Dart analysis for the given package, and returns the result that
  /// applies to that analysis.
  Future<PackageResult> _runDartAnalysisForPackage(
      RepositoryPackage package) async {
    final bool libOnly = getBoolArg(_libOnlyFlag);

    if (libOnly && !package.libDirectory.existsSync()) {
      return PackageResult.skip('No lib/ directory.');
    }

    if (getBoolArg(_downgradeFlag)) {
      if (!await _runPubCommand(package, 'downgrade')) {
        return PackageResult.fail(<String>['Unable to downgrade dependencies']);
      }
    }

    // Analysis runs over the package and all subpackages (unless only lib/ is
    // being analyzed), so all of them need `flutter pub get` run before
    // analyzing. `example` packages can be skipped since 'flutter packages get'
    // automatically runs `pub get` in examples as part of handling the parent
    // directory.
    final List<RepositoryPackage> packagesToGet = <RepositoryPackage>[
      package,
      if (!libOnly) ...await getSubpackages(package).toList(),
    ];
    for (final RepositoryPackage packageToGet in packagesToGet) {
      if (packageToGet.directory.basename != 'example' ||
          !RepositoryPackage(packageToGet.directory.parent)
              .pubspecFile
              .existsSync()) {
        if (!await _runPubCommand(packageToGet, 'get')) {
          if (getBoolArg(_skipIfResolvingFailsFlag)) {
            // Re-run, capturing output, to see if the failure was a resolver
            // failure. (This is slightly inefficient, but this should be a
            // very rare case.)
            const String resolverFailureMessage = 'version solving failed';
            final io.ProcessResult result = await processRunner.run(
                flutterCommand, <String>['pub', 'get'],
                workingDir: packageToGet.directory);
            if ((result.stderr as String).contains(resolverFailureMessage) ||
                (result.stdout as String).contains(resolverFailureMessage)) {
              logWarning('Skipping package due to pub resolution failure.');
              return PackageResult.skip('Resolution failed.');
            }
          }
          return PackageResult.fail(<String>['Unable to get dependencies']);
        }
      }
    }

    if (_hasUnexpectedAnalysisOptions(package)) {
      return PackageResult.fail(<String>['Unexpected local analysis options']);
    }
    final int exitCode = await processRunner.runAndStream(_dartBinaryPath,
        <String>['analyze', '--fatal-infos', if (libOnly) 'lib'],
        workingDir: package.directory);
    if (exitCode != 0) {
      return PackageResult.fail();
    }
    return PackageResult.success();
  }

  Future<bool> _runPubCommand(RepositoryPackage package, String command) async {
    final int exitCode = await processRunner.runAndStream(
        flutterCommand, <String>['pub', command],
        workingDir: package.directory);
    return exitCode == 0;
  }

  /// Runs Gradle lint analysis for the given package, and returns the result
  /// that applies to that analysis.
  Future<PackageResult> _runGradleLintForPackage(
      RepositoryPackage package) async {
    if (!pluginSupportsPlatform(platformAndroid, package,
        requiredMode: PlatformSupport.inline)) {
      return PackageResult.skip(
          'Package does not contain native Android plugin code');
    }

    for (final RepositoryPackage example in package.getExamples()) {
      final GradleProject project = GradleProject(example,
          processRunner: processRunner, platform: platform);

      if (!project.isConfigured()) {
        final bool buildSuccess = await runConfigOnlyBuild(
            example, processRunner, platform, FlutterPlatform.android);
        if (!buildSuccess) {
          printError('Unable to configure Gradle project.');
          return PackageResult.fail(<String>['Unable to configure Gradle.']);
        }
      }

      final String packageName = package.directory.basename;

      // Only lint one build mode to avoid extra work.
      // Only lint the plugin project itself, to avoid failing due to errors in
      // dependencies.
      //
      // TODO(stuartmorgan): Consider adding an XML parser to read and summarize
      //  all results. Currently, only the first three errors will be shown
      //  inline, and the rest have to be checked via the CI-uploaded artifact.
      final int exitCode = await project.runCommand('$packageName:lintDebug');
      if (exitCode != 0) {
        return PackageResult.fail();
      }
    }

    return PackageResult.success();
  }

  /// Analyzes [plugin] for [targetPlatform].
  Future<PackageResult> _runXcodeAnalysisForPackage(
    RepositoryPackage package,
    FlutterPlatform targetPlatform, {
    List<String> extraFlags = const <String>[],
  }) async {
    final String platformString =
        targetPlatform == FlutterPlatform.ios ? 'iOS' : 'macOS';
    if (!pluginSupportsPlatform(targetPlatform.name, package,
        requiredMode: PlatformSupport.inline)) {
      return PackageResult.skip(
          'Package does not contain native $platformString plugin code');
    }

    final Xcode xcode = Xcode(processRunner: processRunner, log: true);
    final List<String> errors = <String>[];
    for (final RepositoryPackage example in package.getExamples()) {
      // See https://github.com/flutter/flutter/issues/172427 for discussion of
      // why this is currently necessary.
      print('Disabling Swift Package Manager...');
      setSwiftPackageManagerState(example, enabled: false);

      // Unconditionally re-run build with --debug --config-only, to ensure that
      // the project is in a debug state even if it was previously configured,
      // and that SwiftPM is disabled.
      print('Running flutter build --config-only...');
      final bool buildSuccess = await runConfigOnlyBuild(
        example,
        processRunner,
        platform,
        targetPlatform,
        buildDebug: true,
      );
      if (!buildSuccess) {
        printError('Unable to prepare native project files.');
        errors.add(
            'Unable to build ${getRelativePosixPath(example.directory, from: package.directory)}.');
        continue;
      }

      // Running tests and static analyzer.
      final String examplePath = getRelativePosixPath(example.directory,
          from: package.directory.parent);
      print('Running $platformString tests and analyzer for $examplePath...');
      final int exitCode = await xcode.runXcodeBuild(
        example.directory,
        platformString,
        // Clean before analyzing to remove cached swiftmodules from previous
        // runs, which can cause conflicts.
        actions: <String>['clean', 'analyze'],
        workspace: '${platformString.toLowerCase()}/Runner.xcworkspace',
        scheme: 'Runner',
        configuration: 'Debug',
        hostPlatform: platform,
        extraFlags: <String>[
          ...extraFlags,
          'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
        ],
      );
      if (exitCode == 0) {
        printSuccess('$examplePath ($platformString) passed analysis.');
      } else {
        printError('$examplePath ($platformString) failed analysis.');
        errors.add(
            '${getRelativePosixPath(example.directory, from: package.directory)} failed analysis.');
      }

      print('Removing Swift Package Manager override...');
      setSwiftPackageManagerState(example, enabled: null);
    }
    return errors.isEmpty
        ? PackageResult.success()
        : PackageResult.fail(errors);
  }
}
