// 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:unified_analytics/unified_analytics.dart';

import '../android/gradle_utils.dart' as gradle;
import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/net.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../base/version.dart';
import '../base/version_range.dart';
import '../convert.dart';
import '../dart/pub.dart';
import '../features.dart';
import '../flutter_manifest.dart';
import '../flutter_project_metadata.dart';
import '../globals.dart' as globals;
import '../ios/code_signing.dart';
import '../macos/swift_package_manager.dart';
import '../macos/swift_packages.dart';
import '../project.dart';
import '../reporting/reporting.dart';
import '../runner/flutter_command.dart';
import 'create_base.dart';

const String kPlatformHelp =
  'The platforms supported by this project. '
  'Platform folders (e.g. android/) will be generated in the target project. '
  'This argument only works when "--template" is set to app or plugin. '
  'When adding platforms to a plugin project, the pubspec.yaml will be updated with the requested platform. '
  'Adding desktop platforms requires the corresponding desktop config setting to be enabled.';

class CreateCommand extends CreateBase {
  CreateCommand({
    super.verboseHelp = false,
  }) {
    addPlatformsOptions(customHelp: kPlatformHelp);
    argParser.addOption(
      'template',
      abbr: 't',
      allowed: FlutterProjectType.enabledValues
          .map<String>((FlutterProjectType e) => e.cliName),
      help: 'Specify the type of project to create.',
      valueHelp: 'type',
      allowedHelp: CliEnum.allowedHelp(FlutterProjectType.enabledValues),
    );
    argParser.addOption(
      'sample',
      abbr: 's',
      help: 'Specifies the Flutter code sample to use as the "main.dart" for an application. Implies '
        '"--template=app". The value should be the sample ID of the desired sample from the API '
        'documentation website (https://api.flutter.dev/). An example can be found at: '
        'https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html',
      valueHelp: 'id',
    );
    argParser.addFlag(
      'empty',
      abbr: 'e',
      help: 'Specifies creating using an application template with a main.dart that is minimal, '
        'including no comments, as a starting point for a new application. Implies "--template=app".',
    );
    argParser.addOption(
      'list-samples',
      help: 'Specifies a JSON output file for a listing of Flutter code samples '
        'that can be created with "--sample".',
      valueHelp: 'path',
    );
  }

  @override
  final String name = 'create';

  @override
  final String description = 'Create a new Flutter project.\n\n'
    'If run on a project that already exists, this will repair the project, recreating any files that are missing.';

  @override
  String get category => FlutterCommandCategory.project;

  @override
  String get invocation => '${runner?.executableName} $name <output directory>';

  @override
  Future<CustomDimensions> get usageValues async {
    return CustomDimensions(
      commandCreateProjectType: stringArg('template'),
      commandCreateAndroidLanguage: stringArg('android-language'),
      commandCreateIosLanguage: stringArg('ios-language'),
    );
  }

  @override
  Future<Event> unifiedAnalyticsUsageValues(String commandPath) async => Event.commandUsageValues(
    workflow: commandPath,
    commandHasTerminal: hasTerminal,
    createProjectType: stringArg('template'),
    createAndroidLanguage: stringArg('android-language'),
    createIosLanguage: stringArg('ios-language'),
  );

  // Lazy-initialize the net utilities with values from the context.
  late final Net _net = Net(
    httpClientFactory: context.get<HttpClientFactory>(),
    logger: globals.logger,
    platform: globals.platform,
  );

  /// The hostname for the Flutter docs for the current channel.
  String get _snippetsHost => globals.flutterVersion.channel == 'stable'
        ? 'api.flutter.dev'
        : 'main-api.flutter.dev';

  Future<String?> _fetchSampleFromServer(String sampleId) async {
    // Sanity check the sampleId
    if (sampleId.contains(RegExp(r'[^-\w\.]'))) {
      throwToolExit('Sample ID "$sampleId" contains invalid characters. Check the ID in the '
        'documentation and try again.');
    }

    final Uri snippetsUri = Uri.https(_snippetsHost, 'snippets/$sampleId.dart');
    final List<int>? data = await _net.fetchUrl(snippetsUri);
    if (data == null || data.isEmpty) {
      return null;
    }
    return utf8.decode(data);
  }

  /// Fetches the samples index file from the Flutter docs website.
  Future<String?> _fetchSamplesIndexFromServer() async {
    final Uri snippetsUri = Uri.https(_snippetsHost, 'snippets/index.json');
    final List<int>? data = await _net.fetchUrl(snippetsUri, maxAttempts: 2);
    if (data == null || data.isEmpty) {
      return null;
    }
    return utf8.decode(data);
  }

  /// Fetches the samples index file from the server and writes it to
  /// [outputFilePath].
  Future<void> _writeSamplesJson(String outputFilePath) async {
    try {
      final File outputFile = globals.fs.file(outputFilePath);
      if (outputFile.existsSync()) {
        throwToolExit('File "$outputFilePath" already exists', exitCode: 1);
      }
      final String? samplesJson = await _fetchSamplesIndexFromServer();
      if (samplesJson == null) {
        throwToolExit('Unable to download samples', exitCode: 2);
      } else {
        outputFile.writeAsStringSync(samplesJson);
        globals.printStatus('Wrote samples JSON to "$outputFilePath"');
      }
    } on Exception catch (e) {
      throwToolExit('Failed to write samples JSON to "$outputFilePath": $e', exitCode: 2);
    }
  }

  FlutterProjectType _getProjectType(Directory projectDir) {
    FlutterProjectType? template;
    FlutterProjectType? detectedProjectType;
    final bool metadataExists = projectDir.absolute.childFile('.metadata').existsSync();
    final String? templateArgument = stringArg('template');
    if (templateArgument != null) {
      template = FlutterProjectType.fromCliName(templateArgument);
    }
    // If the project directory exists and isn't empty, then try to determine the template
    // type from the project directory.
    if (projectDir.existsSync() && projectDir.listSync().isNotEmpty) {
      detectedProjectType = determineTemplateType();
      if (detectedProjectType == null && metadataExists) {
        // We can only be definitive that this is the wrong type if the .metadata file
        // exists and contains a type that we don't understand, or doesn't contain a type.
        throwToolExit('Sorry, unable to detect the type of project to recreate. '
            'Try creating a fresh project and migrating your existing code to '
            'the new project manually.');
      }
    }
    template ??= detectedProjectType ?? FlutterProjectType.app;
    if (detectedProjectType != null && template != detectedProjectType && metadataExists) {
      // We can only be definitive that this is the wrong type if the .metadata file
      // exists and contains a type that doesn't match.
      throwToolExit("The requested template type '${template.cliName}' doesn't match the "
          "existing template type of '${detectedProjectType.cliName}'.");
    }
    return template;
  }

  @override
  Future<FlutterCommandResult> runCommand() async {
    final String? listSamples = stringArg('list-samples');
    if (listSamples != null) {
      // _writeSamplesJson can potentially be long-lived.
      await _writeSamplesJson(listSamples);
      return FlutterCommandResult.success();
    }

    if (argResults!.wasParsed('empty') && argResults!.wasParsed('sample')) {
      throwToolExit(
        'Only one of --empty or --sample may be specified, not both.',
        exitCode: 2,
      );
    }

    validateOutputDirectoryArg();
    String? sampleCode;
    final String? sampleArgument = stringArg('sample');
    final bool emptyArgument = boolArg('empty');
    final FlutterProjectType template = _getProjectType(projectDir);
    if (sampleArgument != null) {
      if (template != FlutterProjectType.app) {
        throwToolExit('Cannot specify --sample with a project type other than '
          '"${FlutterProjectType.app.cliName}"');
      }
      // Fetch the sample from the server.
      sampleCode = await _fetchSampleFromServer(sampleArgument);
    }
    if (emptyArgument && template != FlutterProjectType.app) {
      throwToolExit('The --empty flag is only supported for the app template.');
    }

    final bool generateModule = template == FlutterProjectType.module;
    final bool generateMethodChannelsPlugin = template == FlutterProjectType.plugin;
    final bool generateFfiPackage = template == FlutterProjectType.packageFfi;
    final bool generateFfiPlugin = template == FlutterProjectType.pluginFfi;
    final bool generateFfi = generateFfiPlugin || generateFfiPackage;
    final bool generatePackage = template == FlutterProjectType.package;

    final List<String> platforms = stringsArg('platforms');
    // `--platforms` does not support module or package.
    if (argResults!.wasParsed('platforms') && (generateModule || generatePackage || generateFfiPackage)) {
      final String template = generateModule ? 'module' : 'package';
      throwToolExit(
        'The "--platforms" argument is not supported in $template template.',
        exitCode: 2
      );
    } else if (platforms.isEmpty) {
      throwToolExit('Must specify at least one platform using --platforms',
        exitCode: 2);
    } else if (generateFfiPlugin && argResults!.wasParsed('platforms') && platforms.contains('web')) {
      throwToolExit(
        'The web platform is not supported in plugin_ffi template.',
        exitCode: 2,
      );
    } else if (generateFfi && argResults!.wasParsed('ios-language')) {
      throwToolExit(
        'The "ios-language" option is not supported with the ${template.cliName} '
        'template: the language will always be C or C++.',
        exitCode: 2,
      );
    } else if (generateFfi && argResults!.wasParsed('android-language')) {
      throwToolExit(
        'The "android-language" option is not supported with the ${template.cliName} '
        'template: the language will always be C or C++.',
        exitCode: 2,
      );
    }

    final String organization = await getOrganization();

    final bool overwrite = boolArg('overwrite');
    validateProjectDir(overwrite: overwrite);

    if (boolArg('with-driver-test')) {
      globals.printWarning(
        'The "--with-driver-test" argument has been deprecated and will no longer add a flutter '
        'driver template. Instead, learn how to use package:integration_test by '
        'visiting https://pub.dev/packages/integration_test .'
      );
    }

    final String dartSdk = globals.cache.dartSdkBuild;
    final bool includeIos;
    final bool includeAndroid;
    final bool includeWeb;
    final bool includeLinux;
    final bool includeMacos;
    final bool includeWindows;
    if (template == FlutterProjectType.module) {
      // The module template only supports iOS and Android.
      includeIos = true;
      includeAndroid = true;
      includeWeb = false;
      includeLinux = false;
      includeMacos = false;
      includeWindows = false;
    } else if (template == FlutterProjectType.package) {
      // The package template does not supports any platform.
      includeIos = false;
      includeAndroid = false;
      includeWeb = false;
      includeLinux = false;
      includeMacos = false;
      includeWindows = false;
    } else {
      includeIos = featureFlags.isIOSEnabled && platforms.contains('ios');
      includeAndroid = featureFlags.isAndroidEnabled && platforms.contains('android');
      includeWeb = featureFlags.isWebEnabled && platforms.contains('web');
      includeLinux = featureFlags.isLinuxEnabled && platforms.contains('linux');
      includeMacos = featureFlags.isMacOSEnabled && platforms.contains('macos');
      includeWindows = featureFlags.isWindowsEnabled && platforms.contains('windows');
    }

    String? developmentTeam;
    if (includeIos) {
      developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: globals.processManager,
        platform: globals.platform,
        logger: globals.logger,
        config: globals.config,
        terminal: globals.terminal,
      );
    }

    // The dart project_name is in snake_case, this variable is the Title Case of the Project Name.
    final String titleCaseProjectName = snakeCaseToTitleCase(projectName);

    final Map<String, Object?> templateContext = createTemplateContext(
      organization: organization,
      projectName: projectName,
      titleCaseProjectName: titleCaseProjectName,
      projectDescription: stringArg('description'),
      flutterRoot: flutterRoot,
      withPlatformChannelPluginHook: generateMethodChannelsPlugin,
      withSwiftPackageManager: featureFlags.isSwiftPackageManagerEnabled,
      withFfiPluginHook: generateFfiPlugin,
      withFfiPackage: generateFfiPackage,
      withEmptyMain: emptyArgument,
      androidLanguage: stringArg('android-language'),
      iosLanguage: stringArg('ios-language'),
      iosDevelopmentTeam: developmentTeam,
      ios: includeIos,
      android: includeAndroid,
      web: includeWeb,
      linux: includeLinux,
      macos: includeMacos,
      windows: includeWindows,
      dartSdkVersionBounds: "'>=$dartSdk <4.0.0'",
      implementationTests: boolArg('implementation-tests'),
      agpVersion: gradle.templateAndroidGradlePluginVersion,
      kotlinVersion: gradle.templateKotlinGradlePluginVersion,
      gradleVersion: gradle.templateDefaultGradleVersion,
    );

    final String relativeDirPath = globals.fs.path.relative(projectDirPath);
    final bool creatingNewProject = !projectDir.existsSync() || projectDir.listSync().isEmpty;
    if (creatingNewProject) {
      globals.printStatus('Creating project $relativeDirPath...');
    } else {
      if (sampleCode != null && !overwrite) {
        throwToolExit('Will not overwrite existing project in $relativeDirPath: '
          'must specify --overwrite for samples to overwrite.');
      }
      globals.printStatus('Recreating project $relativeDirPath...');
    }

    final Directory relativeDir = globals.fs.directory(projectDirPath);
    int generatedFileCount = 0;
    final PubContext pubContext;
    switch (template) {
      case FlutterProjectType.app:
        final bool skipWidgetTestsGeneration =
            sampleCode != null || emptyArgument;

        generatedFileCount += await generateApp(
          <String>['app', if (!skipWidgetTestsGeneration) 'app_test_widget'],
          relativeDir,
          templateContext,
          overwrite: overwrite,
          printStatusWhenWriting: !creatingNewProject,
          projectType: template,
        );
        pubContext = PubContext.create;
      case FlutterProjectType.skeleton:
        generatedFileCount += await generateApp(
          <String>['skeleton'],
          relativeDir,
          templateContext,
          overwrite: overwrite,
          printStatusWhenWriting: !creatingNewProject,
          generateMetadata: false,
        );
        pubContext = PubContext.create;
      case FlutterProjectType.module:
        generatedFileCount += await _generateModule(
          relativeDir,
          templateContext,
          overwrite: overwrite,
          printStatusWhenWriting: !creatingNewProject,
        );
        pubContext = PubContext.create;
      case FlutterProjectType.package:
        generatedFileCount += await _generatePackage(
          relativeDir,
          templateContext,
          overwrite: overwrite,
          printStatusWhenWriting: !creatingNewProject,
        );
        pubContext = PubContext.createPackage;
      case FlutterProjectType.plugin:
        generatedFileCount += await _generateMethodChannelPlugin(
          relativeDir,
          templateContext,
          overwrite: overwrite,
          printStatusWhenWriting: !creatingNewProject,
          projectType: template,
        );
        pubContext = PubContext.createPlugin;
      case FlutterProjectType.pluginFfi:
        generatedFileCount += await _generateFfiPlugin(
          relativeDir,
          templateContext,
          overwrite: overwrite,
          printStatusWhenWriting: !creatingNewProject,
          projectType: template,
        );
        pubContext = PubContext.createPlugin;
      case FlutterProjectType.packageFfi:
        generatedFileCount += await _generateFfiPackage(
          relativeDir,
          templateContext,
          overwrite: overwrite,
          printStatusWhenWriting: !creatingNewProject,
          projectType: template,
        );
        pubContext = PubContext.createPackage;
    }

    if (boolArg('pub')) {
      final FlutterProject project = FlutterProject.fromDirectory(relativeDir);
      await pub.get(
        context: pubContext,
        project: project,
        offline: boolArg('offline'),
        outputMode: PubOutputMode.summaryOnly,
      );
      // Setting `includeIos` etc to false as with FlutterProjectType.package
      // causes the example sub directory to not get os sub directories.
      // This will lead to `flutter build ios` to fail in the example.
      // TODO(dacoharkes): Uncouple the app and parent project platforms. https://github.com/flutter/flutter/issues/133874
      // Then this if can be removed.
      if (!generateFfiPackage) {
        await project.ensureReadyForPlatformSpecificTooling(
          androidPlatform: includeAndroid,
          iosPlatform: includeIos,
          linuxPlatform: includeLinux,
          macOSPlatform: includeMacos,
          windowsPlatform: includeWindows,
          webPlatform: includeWeb,
        );
      }
    }
    if (sampleCode != null) {
      _applySample(relativeDir, sampleCode);
    }
    globals.printStatus('Wrote $generatedFileCount files.');
    globals.printStatus('\nAll done!');
    final String application =
      '${emptyArgument ? 'empty ' : ''}${sampleCode != null ? 'sample ' : ''}application';
    if (generatePackage) {
      final String relativeMainPath = globals.fs.path.normalize(globals.fs.path.join(
        relativeDirPath,
        'lib',
        '${templateContext['projectName']}.dart',
      ));
      globals.printStatus('Your package code is in $relativeMainPath');
    } else if (generateModule) {
      final String relativeMainPath = globals.fs.path.normalize(globals.fs.path.join(
          relativeDirPath,
          'lib',
          'main.dart',
      ));
      globals.printStatus('Your module code is in $relativeMainPath.');
    } else if (generateMethodChannelsPlugin || generateFfiPlugin) {
      final String relativePluginPath = globals.fs.path.normalize(globals.fs.path.relative(projectDirPath));
      final List<String> requestedPlatforms = _getUserRequestedPlatforms();
      final String platformsString = requestedPlatforms.join(', ');
      _printPluginDirectoryLocationMessage(relativePluginPath, projectName, platformsString);
      if (!creatingNewProject && requestedPlatforms.isNotEmpty) {
        _printPluginUpdatePubspecMessage(relativePluginPath, platformsString);
      } else if (_getSupportedPlatformsInPlugin(projectDir).isEmpty) {
        _printNoPluginMessage();
      }

      final List<String> platformsToWarn = _getPlatformWarningList(requestedPlatforms);
      if (platformsToWarn.isNotEmpty) {
        _printWarningDisabledPlatform(platformsToWarn);
      }
      final String template = generateMethodChannelsPlugin ? 'plugin' : 'plugin_ffi';
      _printPluginAddPlatformMessage(relativePluginPath, template);
    } else  {
      // Tell the user the next steps.
      final FlutterProject project = FlutterProject.fromDirectory(globals.fs.directory(projectDirPath));
      final FlutterProject app = project.hasExampleApp ? project.example : project;
      final String relativeAppPath = globals.fs.path.normalize(globals.fs.path.relative(app.directory.path));
      final String relativeAppMain = globals.fs.path.join(relativeAppPath, 'lib', 'main.dart');
      final List<String> requestedPlatforms = _getUserRequestedPlatforms();

      // Let them know a summary of the state of their tooling.
      globals.printStatus('''
You can find general documentation for Flutter at: https://docs.flutter.dev/
Detailed API documentation is available at: https://api.flutter.dev/
If you prefer video documentation, consider: https://www.youtube.com/c/flutterdev

In order to run your $application, type:

  \$ cd $relativeAppPath
  \$ flutter run

Your $application code is in $relativeAppMain.
''');
      // Show warning if any selected platform is not enabled
      final List<String> platformsToWarn = _getPlatformWarningList(requestedPlatforms);
      if (platformsToWarn.isNotEmpty) {
        _printWarningDisabledPlatform(platformsToWarn);
      }
    }

    // Show warning for Java/AGP or Java/Gradle incompatibility if building for
    // Android and Java version has been detected.
    if (includeAndroid && globals.java?.version != null) {
      _printIncompatibleJavaAgpGradleVersionsWarning(
        javaVersion: versionToParsableString(globals.java?.version)!,
        templateGradleVersion: templateContext['gradleVersion']! as String,
        templateAgpVersion: templateContext['agpVersion']! as String,
        templateAgpVersionForModule: templateContext['agpVersionForModule']! as String,
        projectType: template,
        projectDirPath: projectDirPath,
      );
    }

    return FlutterCommandResult.success();
  }

  Future<int> _generateModule(
    Directory directory,
    Map<String, Object?> templateContext, {
    bool overwrite = false,
    bool printStatusWhenWriting = true,
  }) async {
    int generatedCount = 0;
    final String? description = argResults!.wasParsed('description')
        ? stringArg('description')
        : 'A new Flutter module project.';
    templateContext['description'] = description;
    generatedCount += await renderTemplate(
      globals.fs.path.join('module', 'common'),
      directory,
      templateContext,
      overwrite: overwrite,
      printStatusWhenWriting: printStatusWhenWriting,
    );
    return generatedCount;
  }

  Future<int> _generatePackage(
    Directory directory,
    Map<String, Object?> templateContext, {
    bool overwrite = false,
    bool printStatusWhenWriting = true,
  }) async {
    int generatedCount = 0;
    final String? description = argResults!.wasParsed('description')
        ? stringArg('description')
        : 'A new Flutter package project.';
    templateContext['description'] = description;
    generatedCount += await renderTemplate(
      'package',
      directory,
      templateContext,
      overwrite: overwrite,
      printStatusWhenWriting: printStatusWhenWriting,
    );
    return generatedCount;
  }

  Future<int> _generateMethodChannelPlugin(
    Directory directory,
    Map<String, Object?> templateContext, {
    bool overwrite = false,
    bool printStatusWhenWriting = true,
    required FlutterProjectType projectType,
  }) async {
    // Plugins only add a platform if it was requested explicitly by the user.
    if (!argResults!.wasParsed('platforms')) {
      for (final String platform in kAllCreatePlatforms) {
        templateContext[platform] = false;
      }
    }
    final List<String> platformsToAdd = _getSupportedPlatformsFromTemplateContext(templateContext);

    final List<String> existingPlatforms = _getSupportedPlatformsInPlugin(directory);
    for (final String existingPlatform in existingPlatforms) {
      // re-generate files for existing platforms
      templateContext[existingPlatform] = true;
    }

    final bool willAddPlatforms = platformsToAdd.isNotEmpty;
    templateContext['no_platforms'] = !willAddPlatforms;
    int generatedCount = 0;
    final String? description = argResults!.wasParsed('description')
        ? stringArg('description')
        : 'A new Flutter plugin project.';
    templateContext['description'] = description;

    final String? projectName = templateContext['projectName'] as String?;
    final List<String> templates = <String>['plugin', 'plugin_shared'];
    if ((templateContext['ios'] == true || templateContext['macos'] == true) && featureFlags.isSwiftPackageManagerEnabled) {
      templates.add('plugin_swift_package_manager');
      templateContext['swiftLibraryName'] = projectName?.replaceAll('_', '-');
      templateContext['swiftToolsVersion'] = minimumSwiftToolchainVersion;
      templateContext['iosSupportedPlatform'] = SwiftPackageManager.iosSwiftPackageSupportedPlatform.format();
      templateContext['macosSupportedPlatform'] = SwiftPackageManager.macosSwiftPackageSupportedPlatform.format();
    } else {
      templates.add('plugin_cocoapods');
    }

    generatedCount += await renderMerged(
      templates,
      directory,
      templateContext,
      overwrite: overwrite,
      printStatusWhenWriting: printStatusWhenWriting,
    );

    final FlutterProject project = FlutterProject.fromDirectory(directory);
    final bool generateAndroid = templateContext['android'] == true;
    if (generateAndroid) {
      gradle.updateLocalProperties(
        project: project, requireAndroidSdk: false);
    }

    final String organization = templateContext['organization']! as String; // Required to make the context.
    final String? androidPluginIdentifier = templateContext['androidIdentifier'] as String?;
    final String exampleProjectName = '${projectName}_example';
    templateContext['projectName'] = exampleProjectName;
    templateContext['androidIdentifier'] = CreateBase.createAndroidIdentifier(organization, exampleProjectName);
    templateContext['iosIdentifier'] = CreateBase.createUTIIdentifier(organization, exampleProjectName);
    templateContext['macosIdentifier'] = CreateBase.createUTIIdentifier(organization, exampleProjectName);
    templateContext['windowsIdentifier'] = CreateBase.createWindowsIdentifier(organization, exampleProjectName);
    templateContext['description'] = 'Demonstrates how to use the $projectName plugin.';
    templateContext['pluginProjectName'] = projectName;
    templateContext['androidPluginIdentifier'] = androidPluginIdentifier;

    generatedCount += await generateApp(
      <String>['app', 'app_test_widget', 'app_integration_test'],
      project.example.directory,
      templateContext,
      overwrite: overwrite,
      pluginExampleApp: true,
      printStatusWhenWriting: printStatusWhenWriting,
      projectType: projectType,
    );
    return generatedCount;
  }

  Future<int> _generateFfiPlugin(
    Directory directory,
    Map<String, Object?> templateContext, {
    bool overwrite = false,
    bool printStatusWhenWriting = true,
    required FlutterProjectType projectType,
  }) async {
    // Plugins only add a platform if it was requested explicitly by the user.
    if (!argResults!.wasParsed('platforms')) {
      for (final String platform in kAllCreatePlatforms) {
        templateContext[platform] = false;
      }
    }
    final List<String> platformsToAdd =
        _getSupportedPlatformsFromTemplateContext(templateContext);

    final List<String> existingPlatforms =
        _getSupportedPlatformsInPlugin(directory);
    for (final String existingPlatform in existingPlatforms) {
      // re-generate files for existing platforms
      templateContext[existingPlatform] = true;
    }

    final bool willAddPlatforms = platformsToAdd.isNotEmpty;
    templateContext['no_platforms'] = !willAddPlatforms;
    int generatedCount = 0;
    final String? description = argResults!.wasParsed('description')
        ? stringArg('description')
        : 'A new Flutter FFI plugin project.';
    templateContext['description'] = description;
    generatedCount += await renderMerged(
      <String>['plugin_ffi', 'plugin_shared'],
      directory,
      templateContext,
      overwrite: overwrite,
      printStatusWhenWriting: printStatusWhenWriting,
    );

    final FlutterProject project = FlutterProject.fromDirectory(directory);
    final bool generateAndroid = templateContext['android'] == true;
    if (generateAndroid) {
      gradle.updateLocalProperties(project: project, requireAndroidSdk: false);
    }

    final String? projectName = templateContext['projectName'] as String?;
    final String organization = templateContext['organization']! as String; // Required to make the context.
    final String? androidPluginIdentifier = templateContext['androidIdentifier'] as String?;
    final String exampleProjectName = '${projectName}_example';
    templateContext['projectName'] = exampleProjectName;
    templateContext['androidIdentifier'] = CreateBase.createAndroidIdentifier(organization, exampleProjectName);
    templateContext['iosIdentifier'] = CreateBase.createUTIIdentifier(organization, exampleProjectName);
    templateContext['macosIdentifier'] = CreateBase.createUTIIdentifier(organization, exampleProjectName);
    templateContext['windowsIdentifier'] = CreateBase.createWindowsIdentifier(organization, exampleProjectName);
    templateContext['description'] = 'Demonstrates how to use the $projectName plugin.';
    templateContext['pluginProjectName'] = projectName;
    templateContext['androidPluginIdentifier'] = androidPluginIdentifier;

    generatedCount += await generateApp(
      <String>['app'],
      project.example.directory,
      templateContext,
      overwrite: overwrite,
      pluginExampleApp: true,
      printStatusWhenWriting: printStatusWhenWriting,
      projectType: projectType,
    );
    return generatedCount;
  }

  Future<int> _generateFfiPackage(
    Directory directory,
    Map<String, Object?> templateContext, {
    bool overwrite = false,
    bool printStatusWhenWriting = true,
    required FlutterProjectType projectType,
  }) async {
    int generatedCount = 0;
    final String? description = argResults!.wasParsed('description')
        ? stringArg('description')
        : 'A new Dart FFI package project.';
    templateContext['description'] = description;
    generatedCount += await renderMerged(
      <String>[
        'package_ffi',
      ],
      directory,
      templateContext,
      overwrite: overwrite,
      printStatusWhenWriting: printStatusWhenWriting,
    );

    final FlutterProject project = FlutterProject.fromDirectory(directory);

    final String? projectName = templateContext['projectName'] as String?;
    final String exampleProjectName = '${projectName}_example';
    templateContext['projectName'] = exampleProjectName;
    templateContext['description'] = 'Demonstrates how to use the $projectName package.';
    templateContext['pluginProjectName'] = projectName;

    generatedCount += await generateApp(
      <String>['app'],
      project.example.directory,
      templateContext,
      overwrite: overwrite,
      pluginExampleApp: true,
      printStatusWhenWriting: printStatusWhenWriting,
      projectType: projectType,
    );
    return generatedCount;
  }

  // Takes an application template and replaces the main.dart with one from the
  // documentation website in sampleCode. Returns the difference in the number
  // of files after applying the sample, since it also deletes the application's
  // test directory (since the template's test doesn't apply to the sample).
  void _applySample(Directory directory, String sampleCode) {
    final File mainDartFile = directory.childDirectory('lib').childFile('main.dart');
    mainDartFile.createSync(recursive: true);
    mainDartFile.writeAsStringSync(sampleCode);
  }

  List<String> _getSupportedPlatformsFromTemplateContext(Map<String, Object?> templateContext) {
    return <String>[
      for (final String platform in kAllCreatePlatforms)
        if (templateContext[platform] == true) platform,
    ];
  }

  // Returns a list of platforms that are explicitly requested by user via `--platforms`.
  List<String> _getUserRequestedPlatforms() {
    if (!argResults!.wasParsed('platforms')) {
      return <String>[];
    }
    return stringsArg('platforms');
  }
}


// Determine what platforms are supported based on generated files.
List<String> _getSupportedPlatformsInPlugin(Directory projectDir) {
  final String pubspecPath = globals.fs.path.join(projectDir.absolute.path, 'pubspec.yaml');
  final FlutterManifest? manifest = FlutterManifest.createFromPath(pubspecPath, fileSystem: globals.fs, logger: globals.logger);
  final Map<String, Object?>? validSupportedPlatforms = manifest?.validSupportedPlatforms;
  final List<String> platforms = validSupportedPlatforms == null
    ? <String>[]
    : validSupportedPlatforms.keys.toList();
  return platforms;
}

void _printPluginDirectoryLocationMessage(String pluginPath, String projectName, String platformsString) {
  final String relativePluginMain = globals.fs.path.join(pluginPath, 'lib', '$projectName.dart');
  final String relativeExampleMain = globals.fs.path.join(pluginPath, 'example', 'lib', 'main.dart');
  globals.printStatus('''

Your plugin code is in $relativePluginMain.

Your example app code is in $relativeExampleMain.

''');
  if (platformsString.isNotEmpty) {
    globals.printStatus('''
Host platform code is in the $platformsString directories under $pluginPath.
To edit platform code in an IDE see https://flutter.dev/developing-packages/#edit-plugin-package.

    ''');
  }
}

void _printPluginUpdatePubspecMessage(String pluginPath, String platformsString) {
  globals.printStatus('''
You need to update $pluginPath/pubspec.yaml to support $platformsString.
''', emphasis: true, color: TerminalColor.red);
}

void _printNoPluginMessage() {
    globals.printError('''
You've created a plugin project that doesn't yet support any platforms.
''');
}

void _printPluginAddPlatformMessage(String pluginPath, String template) {
  globals.printStatus('''
To add platforms, run `flutter create -t $template --platforms <platforms> .` under $pluginPath.
For more information, see https://flutter.dev/go/plugin-platforms.

''');
}

// returns a list disabled, but requested platforms
List<String> _getPlatformWarningList(List<String> requestedPlatforms) {
  final List<String> platformsToWarn = <String>[
  if (requestedPlatforms.contains('web') && !featureFlags.isWebEnabled)
    'web',
  if (requestedPlatforms.contains('macos') && !featureFlags.isMacOSEnabled)
    'macos',
  if (requestedPlatforms.contains('windows') && !featureFlags.isWindowsEnabled)
    'windows',
  if (requestedPlatforms.contains('linux') && !featureFlags.isLinuxEnabled)
    'linux',
  ];

  return platformsToWarn;
}

void _printWarningDisabledPlatform(List<String> platforms) {
  final List<String> desktop = <String>[];
  final List<String> web = <String>[];

  for (final String platform in platforms) {
    switch (platform) {
      case 'web':
        web.add(platform);
      case 'macos' || 'windows' || 'linux':
        desktop.add(platform);
    }
  }

  if (desktop.isNotEmpty) {
    final String platforms = desktop.length > 1 ? 'platforms' : 'platform';
    final String verb = desktop.length > 1 ? 'are' : 'is';

    globals.printStatus('''
The desktop $platforms: ${desktop.join(', ')} $verb currently not supported on your local environment.
For more details, see: https://flutter.dev/desktop
''');
  }
  if (web.isNotEmpty) {
    globals.printStatus('''
The web is currently not supported on your local environment.
For more details, see: https://flutter.dev/docs/get-started/web
''');
  }
}

// Prints a warning if the specified Java version conflicts with either the
// template Gradle or AGP version.
//
// Assumes the specified templateGradleVersion and templateAgpVersion are
// compatible, meaning that the Java version may only conflict with one of the
// template Gradle or AGP versions.
void _printIncompatibleJavaAgpGradleVersionsWarning({
  required String javaVersion,
  required String templateGradleVersion,
  required String templateAgpVersion,
  required String templateAgpVersionForModule,
  required FlutterProjectType projectType,
  required String projectDirPath}) {
  // Determine if the Java version specified conflicts with the template Gradle or AGP version.
  final bool javaGradleVersionsCompatible = gradle.validateJavaAndGradle(globals.logger, javaV: javaVersion, gradleV: templateGradleVersion);
  bool javaAgpVersionsCompatible = gradle.validateJavaAndAgp(globals.logger, javaV: javaVersion, agpV: templateAgpVersion);
  String relevantTemplateAgpVersion = templateAgpVersion;

  if (projectType == FlutterProjectType.module && Version.parse(templateAgpVersion)! < Version.parse(templateAgpVersionForModule)!) {
    // If a module is being created, make sure to check for Java/AGP compatibility between the highest used version of AGP in the module template.
    javaAgpVersionsCompatible = gradle.validateJavaAndAgp(globals.logger, javaV: javaVersion, agpV: templateAgpVersionForModule);
    relevantTemplateAgpVersion = templateAgpVersionForModule;
  }

  if (javaGradleVersionsCompatible && javaAgpVersionsCompatible) {
    return;
  }

  // Determine header of warning with recommended fix of re-configuring Java version.
  final String incompatibleVersionsAndRecommendedOptionMessage = getIncompatibleJavaGradleAgpMessageHeader(javaGradleVersionsCompatible, templateGradleVersion, relevantTemplateAgpVersion, projectType.cliName);

  if (!javaGradleVersionsCompatible) {

    if (projectType == FlutterProjectType.plugin || projectType == FlutterProjectType.pluginFfi) {
      // Only impacted files could be in sample code.
      return;
    }

    // Gradle template version incompatible with Java version.
    final gradle.JavaGradleCompat? validCompatibleGradleVersionRange = gradle.getValidGradleVersionRangeForJavaVersion(globals.logger, javaV: javaVersion);
    final String compatibleGradleVersionMessage = validCompatibleGradleVersionRange == null ? '' : ' (compatible Gradle version range: ${validCompatibleGradleVersionRange.gradleMin} - ${validCompatibleGradleVersionRange.gradleMax})';

    globals.printWarning('''
$incompatibleVersionsAndRecommendedOptionMessage

Alternatively, to continue using your configured Java version, update the Gradle
version specified in the following file to a compatible Gradle version$compatibleGradleVersionMessage:
${_getGradleWrapperPropertiesFilePath(projectType, projectDirPath)}

You may also update the Gradle version used by running
`./gradlew wrapper --gradle-version=<COMPATIBLE_GRADLE_VERSION>`.

See
https://docs.gradle.org/current/userguide/compatibility.html#java for details
on compatible Java/Gradle versions, and see
https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:upgrading_wrapper
for more details on using the Gradle Wrapper command to update the Gradle version
used.
''',
      emphasis: true
    );
    return;
  }

  // AGP template version incompatible with Java version.
  final gradle.JavaAgpCompat? minimumCompatibleAgpVersion = gradle.getMinimumAgpVersionForJavaVersion(globals.logger, javaV: javaVersion);
  final String compatibleAgpVersionMessage = minimumCompatibleAgpVersion == null ? '' : ' (minimum compatible AGP version: ${minimumCompatibleAgpVersion.agpMin})';
  final String gradleBuildFilePaths = '    -  ${_getBuildGradleConfigurationFilePaths(projectType, projectDirPath)!.join('\n    - ')}';

  globals.printWarning('''
$incompatibleVersionsAndRecommendedOptionMessage

Alternatively, to continue using your configured Java version, update the AGP
version specified in the following files to a compatible AGP
version$compatibleAgpVersionMessage as necessary:
$gradleBuildFilePaths

See
https://developer.android.com/build/releases/gradle-plugin for details on
compatible Java/AGP versions.
''',
    emphasis: true
  );
}

// Returns incompatible Java/template Gradle/template AGP message header based
// on incompatibility and project type.
@visibleForTesting
String getIncompatibleJavaGradleAgpMessageHeader(
  bool javaGradleVersionsCompatible,
  String templateGradleVersion,
  String templateAgpVersion,
  String projectType) {
  final String incompatibleDependency = javaGradleVersionsCompatible ? 'Android Gradle Plugin (AGP)' :'Gradle' ;
  final String incompatibleDependencyVersion = javaGradleVersionsCompatible ? 'AGP version $templateAgpVersion' : 'Gradle version $templateGradleVersion';
  final VersionRange validJavaRange = gradle.getJavaVersionFor(gradleV: templateGradleVersion, agpV: templateAgpVersion);
  // validJavaRange should have non-null versionMin and versionMax since it based on our template AGP and Gradle versions.
  final String validJavaRangeMessage = '(Java ${validJavaRange.versionMin!} <= compatible Java version < Java ${validJavaRange.versionMax!})';

  return '''
The configured version of Java detected may conflict with the $incompatibleDependency version in your new Flutter $projectType.

[RECOMMENDED] If so, to keep the default $incompatibleDependencyVersion, make
sure to download a compatible Java version
$validJavaRangeMessage.
You may configure this compatible Java version by running:
`flutter config --jdk-dir=<JDK_DIRECTORY>`
Note that this is a global configuration for Flutter.
''';
}

// Returns path of the gradle-wrapper.properties file for the specified
// generated project type.
String? _getGradleWrapperPropertiesFilePath(FlutterProjectType projectType, String projectDirPath) {
  String gradleWrapperPropertiesFilePath = '';
  switch (projectType) {
      case FlutterProjectType.app:
      case FlutterProjectType.skeleton:
        gradleWrapperPropertiesFilePath = globals.fs.path.join(projectDirPath, 'android/gradle/wrapper/gradle-wrapper.properties');
      case FlutterProjectType.module:
        gradleWrapperPropertiesFilePath = globals.fs.path.join(projectDirPath, '.android/gradle/wrapper/gradle-wrapper.properties');
      case FlutterProjectType.plugin:
      case FlutterProjectType.pluginFfi:
      case FlutterProjectType.package:
      case FlutterProjectType.packageFfi:
        // TODO(camsim99): Add relevant file path for packageFfi when Android is supported.
        // No gradle-wrapper.properties files not part of sample code that
        // can be determined.
        return null;
  }
  return gradleWrapperPropertiesFilePath;
}

// Returns the path(s) of the build.gradle file(s) for the specified generated
// project type.
List<String>? _getBuildGradleConfigurationFilePaths(FlutterProjectType projectType, String projectDirPath) {
  final List<String> buildGradleConfigurationFilePaths = <String>[];
  switch (projectType) {
      case FlutterProjectType.app:
      case FlutterProjectType.skeleton:
      case FlutterProjectType.pluginFfi:
        buildGradleConfigurationFilePaths.add(globals.fs.path.join(projectDirPath, 'android/build.gradle'));
      case FlutterProjectType.module:
        const String moduleBuildGradleFilePath = '.android/build.gradle';
        const String moduleAppBuildGradleFlePath = '.android/app/build.gradle';
        const String moduleFlutterBuildGradleFilePath = '.android/Flutter/build.gradle';
        buildGradleConfigurationFilePaths.addAll(<String>[
          globals.fs.path.join(projectDirPath, moduleBuildGradleFilePath),
          globals.fs.path.join(projectDirPath, moduleAppBuildGradleFlePath),
          globals.fs.path.join(projectDirPath, moduleFlutterBuildGradleFilePath),
        ]);
      case FlutterProjectType.plugin:
        buildGradleConfigurationFilePaths.add(globals.fs.path.join(projectDirPath, 'android/app/build.gradle'));
      case FlutterProjectType.package:
      case FlutterProjectType.packageFfi:
        // TODO(camsim99): Add any relevant file paths for packageFfi when Android is supported.
        // No build.gradle file because there is no platform-specific implementation.
        return null;
  }
  return buildGradleConfigurationFilePaths;
}
