// 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 '../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,
      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:
        generatedFileCount += await generateApp(
          <String>['app', '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);
    }
    if (sampleCode != null || emptyArgument) {
      generatedFileCount += _removeTestDir(relativeDir);
    }
    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;
    generatedCount += await renderMerged(
      <String>['plugin', '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', '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);
  }

  int _removeTestDir(Directory directory) {
    final Directory testDir = directory.childDirectory('test');
    if (!testDir.existsSync()) {
      return 0;
    }
    final List<FileSystemEntity> files = testDir.listSync(recursive: true);
    try {
      testDir.deleteSync(recursive: true);
    } on FileSystemException catch (exception) {
      throwToolExit('Failed to delete test directory: $exception');
    }
    return -files.length;
  }

  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;
}
