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

import '../android/android.dart' as android_common;
import '../android/android_workflow.dart';
import '../android/gradle_utils.dart' as gradle;
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../build_system/build_system.dart';
import '../cache.dart';
import '../convert.dart';
import '../dart/generate_synthetic_packages.dart';
import '../flutter_project_metadata.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../runner/flutter_command.dart';
import '../template.dart';

const List<String> _kAvailablePlatforms = <String>[
  'ios',
  'android',
  'windows',
  'linux',
  'macos',
  'web',
];

/// A list of all possible create platforms, even those that may not be enabled
/// with the current config.
const List<String> kAllCreatePlatforms = <String>[
  'ios',
  'android',
  'windows',
  'linux',
  'macos',
  'web',
];

const String _kDefaultPlatformArgumentHelp =
    '(required) The platforms supported by this project. '
    'Platform folders (e.g. android/) will be generated in the target project. '
    'Adding desktop platforms requires the corresponding desktop config setting to be enabled.';

/// Common behavior for `flutter create` commands.
abstract class CreateBase extends FlutterCommand {
  CreateBase({
    required bool verboseHelp,
  }) {
    argParser.addFlag(
      'pub',
      defaultsTo: true,
      help:
          'Whether to run "flutter pub get" after the project has been created.',
    );
    argParser.addFlag(
      'offline',
      help:
          'When "flutter pub get" is run by the create command, this indicates '
          'whether to run it in offline mode or not. In offline mode, it will need to '
          'have all dependencies already available in the pub cache to succeed.',
    );
    argParser.addFlag(
      'with-driver-test',
      help: '(deprecated) Historically, this added a flutter_driver dependency and generated a '
            'sample "flutter drive" test. Now it does nothing. Consider using the '
            '"integration_test" package: https://pub.dev/packages/integration_test',
      hide: !verboseHelp,
    );
    argParser.addFlag(
      'overwrite',
      help: 'When performing operations, overwrite existing files.',
    );
    argParser.addOption(
      'description',
      defaultsTo: 'A new Flutter project.',
      help:
          'The description to use for your new Flutter project. This string ends up in the pubspec.yaml file.',
    );
    argParser.addOption(
      'org',
      defaultsTo: 'com.example',
      help:
          'The organization responsible for your new Flutter project, in reverse domain name notation. '
          'This string is used in Java package names and as prefix in the iOS bundle identifier.',
    );
    argParser.addOption(
      'project-name',
      help:
          'The project name for this new Flutter project. This must be a valid dart package name.',
    );
    argParser.addOption(
      'ios-language',
      abbr: 'i',
      defaultsTo: 'swift',
      allowed: <String>['objc', 'swift'],
      help: 'The language to use for iOS-specific code, either Objective-C (legacy) or Swift (recommended).'
    );
    argParser.addOption(
      'android-language',
      abbr: 'a',
      defaultsTo: 'kotlin',
      allowed: <String>['java', 'kotlin'],
      help: 'The language to use for Android-specific code, either Java (legacy) or Kotlin (recommended).',
    );
    argParser.addFlag(
      'skip-name-checks',
      help:
          'Allow the creation of applications and plugins with invalid names. '
          'This is only intended to enable testing of the tool itself.',
      hide: !verboseHelp,
    );
    argParser.addFlag(
      'implementation-tests',
      help:
          'Include implementation tests that verify the template functions correctly. '
          'This is only intended to enable testing of the tool itself.',
      hide: !verboseHelp,
    );
    argParser.addOption(
      'initial-create-revision',
      help: 'The Flutter SDK git commit hash to store in .migrate_config. This parameter is used by the tool '
            'internally and should generally not be used manually.',
      hide: !verboseHelp,
    );
  }

  /// Pattern for a Windows file system drive (e.g. "D:").
  ///
  /// `dart:io` does not recognize strings matching this pattern as absolute
  /// paths, as they have no top level back-slash; however, users often specify
  /// this
  @visibleForTesting
  static final RegExp kWindowsDrivePattern = RegExp(r'^[a-zA-Z]:$');

  /// The output directory of the command.
  @protected
  @visibleForTesting
  Directory get projectDir {
    final String argProjectDir = argResults!.rest.first;
    if (globals.platform.isWindows && kWindowsDrivePattern.hasMatch(argProjectDir)) {
      throwToolExit(
        'You attempted to create a flutter project at the path "$argProjectDir", which is the name of a drive. This '
        'is usually a mistake--you probably want to specify a containing directory, like "$argProjectDir\\app_name". '
        'If you really want it at the drive root, re-run the command with the root directory after the drive, like '
        '"$argProjectDir\\".',
      );
    }
    return globals.fs.directory(argResults!.rest.first);
  }

  /// The normalized absolute path of [projectDir].
  @protected
  String get projectDirPath {
    return globals.fs.path.normalize(projectDir.absolute.path);
  }

  /// Adds a `--platforms` argument.
  ///
  /// The help message of the argument is replaced with `customHelp` if `customHelp` is not null.
  @protected
  void addPlatformsOptions({String? customHelp}) {
    argParser.addMultiOption('platforms',
      help: customHelp ?? _kDefaultPlatformArgumentHelp,
      aliases: <String>[ 'platform' ],
      defaultsTo: <String>[
        ..._kAvailablePlatforms,
      ],
      allowed: <String>[
        ..._kAvailablePlatforms,
      ],
    );
  }

  /// Throw with exit code 2 if the output directory is invalid.
  @protected
  void validateOutputDirectoryArg() {
    final List<String>? rest = argResults?.rest;
    if (rest == null || rest.isEmpty) {
      throwToolExit(
        'No option specified for the output directory.\n$usage',
        exitCode: 2,
      );
    }

    if (rest.length > 1) {
      String message = 'Multiple output directories specified.';
      for (final String arg in rest) {
        if (arg.startsWith('-')) {
          message += '\nTry moving $arg to be immediately following $name';
          break;
        }
      }
      throwToolExit(message, exitCode: 2);
    }
  }

  /// Gets the flutter root directory.
  @protected
  String get flutterRoot => Cache.flutterRoot!;

  /// Determines the project type in an existing flutter project.
  ///
  /// If it has a .metadata file with the project_type in it, use that.
  /// If it has an android dir and an android/app dir, it's a legacy app
  /// If it has an ios dir and an ios/Flutter dir, it's a legacy app
  /// Otherwise, we don't presume to know what type of project it could be, since
  /// many of the files could be missing, and we can't really tell definitively.
  ///
  /// Throws assertion if [projectDir] does not exist or empty.
  /// Returns null if no project type can be determined.
  @protected
  FlutterProjectType? determineTemplateType() {
    assert(projectDir.existsSync() && projectDir.listSync().isNotEmpty);
    final File metadataFile = globals.fs
        .file(globals.fs.path.join(projectDir.absolute.path, '.metadata'));
    final FlutterProjectMetadata projectMetadata =
        FlutterProjectMetadata(metadataFile, globals.logger);
    final FlutterProjectType? projectType = projectMetadata.projectType;
    if (projectType != null) {
      return projectType;
    }

    bool exists(List<String> path) {
      return globals.fs
          .directory(globals.fs.path
              .joinAll(<String>[projectDir.absolute.path, ...path]))
          .existsSync();
    }

    // There either wasn't any metadata, or it didn't contain the project type,
    // so try and figure out what type of project it is from the existing
    // directory structure.
    if (exists(<String>['android', 'app']) ||
        exists(<String>['ios', 'Runner']) ||
        exists(<String>['ios', 'Flutter'])) {
      return FlutterProjectType.app;
    }
    // Since we can't really be definitive on nearly-empty directories, err on
    // the side of prudence and just say we don't know.
    return null;
  }

  /// Determines the organization.
  ///
  /// If `--org` is specified in the command, returns that directly.
  /// If `--org` is not specified, returns the organization from the existing project.
  @protected
  Future<String> getOrganization() async {
    String? organization = stringArg('org');
    if (!argResults!.wasParsed('org')) {
      final FlutterProject project = FlutterProject.fromDirectory(projectDir);
      final Set<String> existingOrganizations = await project.organizationNames;
      if (existingOrganizations.length == 1) {
        organization = existingOrganizations.first;
      } else if (existingOrganizations.length > 1) {
        throwToolExit(
            'Ambiguous organization in existing files: $existingOrganizations. '
            'The --org command line argument must be specified to recreate project.');
      }
    }
    if (organization == null) {
      throwToolExit('The --org command line argument must be specified to create a project.');
    }
    return organization;
  }

  /// Throws with exit 2 if the project directory is illegal.
  @protected
  void validateProjectDir({bool overwrite = false}) {
    if (globals.fs.path.isWithin(flutterRoot, projectDirPath)) {
      // Make exception for dev and examples to facilitate example project development.
      final String examplesDirectory = globals.fs.path.join(flutterRoot, 'examples');
      final String devDirectory = globals.fs.path.join(flutterRoot, 'dev');
      if (!globals.fs.path.isWithin(examplesDirectory, projectDirPath) &&
          !globals.fs.path.isWithin(devDirectory, projectDirPath)) {
        throwToolExit(
            'Cannot create a project within the Flutter SDK. '
                "Target directory '$projectDirPath' is within the Flutter SDK at '$flutterRoot'.",
            exitCode: 2);
      }
    }

    // If the destination directory is actually a file, then we refuse to
    // overwrite, on the theory that the user probably didn't expect it to exist.
    if (globals.fs.isFileSync(projectDirPath)) {
      final String message =
          "Invalid project name: '$projectDirPath' - refers to an existing file.";
      throwToolExit(
          overwrite
              ? '$message Refusing to overwrite a file with a directory.'
              : message,
          exitCode: 2);
    }

    if (overwrite) {
      return;
    }

    final FileSystemEntityType type = globals.fs.typeSync(projectDirPath);

    switch (type) { // ignore: exhaustive_cases, https://github.com/dart-lang/linter/issues/3017
      case FileSystemEntityType.file:
        // Do not overwrite files.
        throwToolExit("Invalid project name: '$projectDirPath' - file exists.",
            exitCode: 2);
      case FileSystemEntityType.link:
        // Do not overwrite links.
        throwToolExit("Invalid project name: '$projectDirPath' - refers to a link.",
            exitCode: 2);
      case FileSystemEntityType.directory:
      case FileSystemEntityType.notFound:
        break;
    }
  }

  /// Gets the project name based.
  ///
  /// Use the current directory path name if the `--project-name` is not specified explicitly.
  @protected
  String get projectName {
    final String projectName =
        stringArg('project-name') ?? globals.fs.path.basename(projectDirPath);
    if (!boolArg('skip-name-checks')) {
      final String? error = _validateProjectName(projectName);
      if (error != null) {
        throwToolExit(error);
      }
    }
    return projectName;
  }

  /// Creates a template to use for [renderTemplate].
  @protected
  Map<String, Object?> createTemplateContext({
    required String organization,
    required String projectName,
    required String titleCaseProjectName,
    String? projectDescription,
    String? androidLanguage,
    String? iosDevelopmentTeam,
    String? iosLanguage,
    required String flutterRoot,
    required String dartSdkVersionBounds,
    String? agpVersion,
    String? kotlinVersion,
    String? gradleVersion,
    bool withPlatformChannelPluginHook = false,
    bool withFfiPluginHook = false,
    bool withEmptyMain = false,
    bool ios = false,
    bool android = false,
    bool web = false,
    bool linux = false,
    bool macos = false,
    bool windows = false,
    bool implementationTests = false,
  }) {
    final String pluginDartClass = _createPluginClassName(projectName);
    final String pluginClass = pluginDartClass.endsWith('Plugin')
        ? pluginDartClass
        : '${pluginDartClass}Plugin';
    final String pluginClassSnakeCase = snakeCase(pluginClass);
    final String pluginClassCapitalSnakeCase =
        pluginClassSnakeCase.toUpperCase();
    final String pluginClassLowerCamelCase =
        pluginClass[0].toLowerCase() + pluginClass.substring(1);
    final String appleIdentifier =
        createUTIIdentifier(organization, projectName);
    final String androidIdentifier =
        createAndroidIdentifier(organization, projectName);
    final String windowsIdentifier =
        createWindowsIdentifier(organization, projectName);
    // Linux uses the same scheme as the Android identifier.
    // https://developer.gnome.org/gio/stable/GApplication.html#g-application-id-is-valid
    final String linuxIdentifier = androidIdentifier;

    return <String, Object?>{
      'organization': organization,
      'projectName': projectName,
      'titleCaseProjectName': titleCaseProjectName,
      'androidIdentifier': androidIdentifier,
      'iosIdentifier': appleIdentifier,
      'macosIdentifier': appleIdentifier,
      'linuxIdentifier': linuxIdentifier,
      'windowsIdentifier': windowsIdentifier,
      'description': projectDescription,
      'dartSdk': '$flutterRoot/bin/cache/dart-sdk',
      'androidMinApiLevel': android_common.minApiLevel,
      'androidSdkVersion': kAndroidSdkMinVersion,
      'pluginClass': pluginClass,
      'pluginClassSnakeCase': pluginClassSnakeCase,
      'pluginClassLowerCamelCase': pluginClassLowerCamelCase,
      'pluginClassCapitalSnakeCase': pluginClassCapitalSnakeCase,
      'pluginDartClass': pluginDartClass,
      'pluginProjectUUID': const Uuid().v4().toUpperCase(),
      'withFfiPluginHook': withFfiPluginHook,
      'withPlatformChannelPluginHook': withPlatformChannelPluginHook,
      'withPluginHook': withFfiPluginHook || withPlatformChannelPluginHook,
      'withEmptyMain': withEmptyMain,
      'androidLanguage': androidLanguage,
      'iosLanguage': iosLanguage,
      'hasIosDevelopmentTeam': iosDevelopmentTeam != null && iosDevelopmentTeam.isNotEmpty,
      'iosDevelopmentTeam': iosDevelopmentTeam ?? '',
      'flutterRevision': globals.flutterVersion.frameworkRevision,
      'flutterChannel': globals.flutterVersion.channel,
      'ios': ios,
      'android': android,
      'web': web,
      'linux': linux,
      'macos': macos,
      'windows': windows,
      'year': DateTime.now().year,
      'dartSdkVersionBounds': dartSdkVersionBounds,
      'implementationTests': implementationTests,
      'agpVersion': agpVersion,
      'kotlinVersion': kotlinVersion,
      'gradleVersion': gradleVersion,
      'gradleVersionForModule': gradle.templateDefaultGradleVersionForModule,
      'compileSdkVersion': gradle.compileSdkVersion,
      'minSdkVersion': gradle.minSdkVersion,
      'ndkVersion': gradle.ndkVersion,
      'targetSdkVersion': gradle.targetSdkVersion,
    };
  }

  /// Renders the template, generate files into `directory`.
  ///
  /// `templateName` should match one of directory names under flutter_tools/template/.
  /// If `overwrite` is true, overwrites existing files, `overwrite` defaults to `false`.
  @protected
  Future<int> renderTemplate(
    String templateName,
    Directory directory,
    Map<String, Object?> context, {
    bool overwrite = false,
    bool printStatusWhenWriting = true,
  }) async {
    final Template template = await Template.fromName(
      templateName,
      fileSystem: globals.fs,
      logger: globals.logger,
      templateRenderer: globals.templateRenderer,
      templateManifest: _templateManifest,
    );
    return template.render(
      directory,
      context,
      overwriteExisting: overwrite,
      printStatusWhenWriting: printStatusWhenWriting,
    );
  }

  /// Merges named templates into a single template, output to `directory`.
  ///
  /// `names` should match directory names under flutter_tools/template/.
  ///
  /// If `overwrite` is true, overwrites existing files, `overwrite` defaults to `false`.
  @protected
  Future<int> renderMerged(
    List<String> names,
    Directory directory,
    Map<String, Object?> context, {
    bool overwrite = false,
    bool printStatusWhenWriting = true,
  }) async {
    final Template template = await Template.merged(
      names,
      directory,
      fileSystem: globals.fs,
      logger: globals.logger,
      templateRenderer: globals.templateRenderer,
      templateManifest: _templateManifest,
    );
    return template.render(
      directory,
      context,
      overwriteExisting: overwrite,
      printStatusWhenWriting: printStatusWhenWriting,
    );
  }

  /// Generate application project in the `directory` using `templateContext`.
  ///
  /// If `overwrite` is true, overwrites existing files, `overwrite` defaults to `false`.
  @protected
  Future<int> generateApp(
    List<String> templateNames,
    Directory directory,
    Map<String, Object?> templateContext, {
    bool overwrite = false,
    bool pluginExampleApp = false,
    bool printStatusWhenWriting = true,
    bool generateMetadata = true,
    FlutterProjectType? projectType,
  }) async {
    int generatedCount = 0;
    generatedCount += await renderMerged(
      <String>[...templateNames, 'app_shared'],
      directory,
      templateContext,
      overwrite: overwrite,
      printStatusWhenWriting: printStatusWhenWriting,
    );
    final FlutterProject project = FlutterProject.fromDirectory(directory);
    if (templateContext['android'] == true) {
      generatedCount += _injectGradleWrapper(project);
    }

    final bool androidPlatform = templateContext['android'] as bool? ?? false;
    final bool iosPlatform = templateContext['ios'] as bool? ?? false;
    final bool linuxPlatform = templateContext['linux'] as bool? ?? false;
    final bool macOSPlatform = templateContext['macos'] as bool? ?? false;
    final bool windowsPlatform = templateContext['windows'] as bool? ?? false;
    final bool webPlatform = templateContext['web'] as bool? ?? false;

    if (boolArg('pub')) {
      final Environment environment = Environment(
        artifacts: globals.artifacts!,
        logger: globals.logger,
        cacheDir: globals.cache.getRoot(),
        engineVersion: globals.flutterVersion.engineRevision,
        fileSystem: globals.fs,
        flutterRootDir: globals.fs.directory(Cache.flutterRoot),
        outputDir: globals.fs.directory(getBuildDirectory()),
        processManager: globals.processManager,
        platform: globals.platform,
        usage: globals.flutterUsage,
        projectDir: project.directory,
        generateDartPluginRegistry: true,
      );

      // Generate the l10n synthetic package that will be injected into the
      // package_config in the call to pub.get() below.
      await generateLocalizationsSyntheticPackage(
        environment: environment,
        buildSystem: globals.buildSystem,
      );
    }
    final List<SupportedPlatform> platformsForMigrateConfig = <SupportedPlatform>[SupportedPlatform.root];
    if (androidPlatform) {
      gradle.updateLocalProperties(project: project, requireAndroidSdk: false);
      platformsForMigrateConfig.add(SupportedPlatform.android);
    }
    if (iosPlatform) {
      platformsForMigrateConfig.add(SupportedPlatform.ios);
    }
    if (linuxPlatform) {
      platformsForMigrateConfig.add(SupportedPlatform.linux);
    }
    if (macOSPlatform) {
      platformsForMigrateConfig.add(SupportedPlatform.macos);
    }
    if (webPlatform) {
      platformsForMigrateConfig.add(SupportedPlatform.web);
    }
    if (windowsPlatform) {
      platformsForMigrateConfig.add(SupportedPlatform.windows);
    }
    if (templateContext['fuchsia'] == true) {
      platformsForMigrateConfig.add(SupportedPlatform.fuchsia);
    }
    if (generateMetadata) {
      final File metadataFile = globals.fs
          .file(globals.fs.path.join(projectDir.absolute.path, '.metadata'));
      final FlutterProjectMetadata metadata = FlutterProjectMetadata.explicit(
        file: metadataFile,
        versionRevision: globals.flutterVersion.frameworkRevision,
        versionChannel: globals.flutterVersion.channel,
        projectType: projectType,
        migrateConfig: MigrateConfig(),
        logger: globals.logger);
      metadata.populate(
        platforms: platformsForMigrateConfig,
        projectDirectory: directory,
        update: false,
        currentRevision: stringArg('initial-create-revision') ?? globals.flutterVersion.frameworkRevision,
        createRevision: globals.flutterVersion.frameworkRevision,
        logger: globals.logger,
      );
      metadata.writeFile();
    }

    return generatedCount;
  }

  /// Creates an android identifier.
  ///
  /// Android application ID is specified in: https://developer.android.com/studio/build/application-id
  /// All characters must be alphanumeric or an underscore [a-zA-Z0-9_].
  static String createAndroidIdentifier(String organization, String name) {
    String tmpIdentifier = '$organization.$name';
    final RegExp disallowed = RegExp(r'[^\w\.]');
    tmpIdentifier = tmpIdentifier.replaceAll(disallowed, '');

    // It must have at least two segments (one or more dots).
    final List<String> segments = tmpIdentifier
        .split('.')
        .where((String segment) => segment.isNotEmpty)
        .toList();
    while (segments.length < 2) {
      segments.add('untitled');
    }

    // Each segment must start with a letter.
    final RegExp segmentPatternRegex = RegExp(r'^[a-zA-Z][\w]*$');
    final List<String> prefixedSegments = segments.map((String segment) {
      if (!segmentPatternRegex.hasMatch(segment)) {
        return 'u$segment';
      }
      return segment;
    }).toList();
    return prefixedSegments.join('.');
  }

  /// Creates a Windows package name.
  ///
  /// Package names must be a globally unique, commonly a GUID.
  static String createWindowsIdentifier(String organization, String name) {
    return const Uuid().v4().toUpperCase();
  }

  String _createPluginClassName(String name) {
    final String camelizedName = camelCase(name);
    return camelizedName[0].toUpperCase() + camelizedName.substring(1);
  }

  /// Create a UTI (https://en.wikipedia.org/wiki/Uniform_Type_Identifier) from a base name
  static String createUTIIdentifier(String organization, String name) {
    name = camelCase(name);
    String tmpIdentifier = '$organization.$name';
    final RegExp disallowed = RegExp(r'[^a-zA-Z0-9\-\.\u0080-\uffff]+');
    tmpIdentifier = tmpIdentifier.replaceAll(disallowed, '');

    // It must have at least two segments (one or more dots).
    final List<String> segments = tmpIdentifier
        .split('.')
        .where((String segment) => segment.isNotEmpty)
        .toList();
    while (segments.length < 2) {
      segments.add('untitled');
    }

    return segments.join('.');
  }

  late final Set<Uri> _templateManifest = _computeTemplateManifest();
  Set<Uri> _computeTemplateManifest() {
    final String flutterToolsAbsolutePath = globals.fs.path.join(
      Cache.flutterRoot!,
      'packages',
      'flutter_tools',
    );
    final String manifestPath = globals.fs.path.join(
      flutterToolsAbsolutePath,
      'templates',
      'template_manifest.json',
    );
    final Map<String, Object?> manifest = json.decode(
      globals.fs.file(manifestPath).readAsStringSync(),
    ) as Map<String, Object?>;
    return Set<Uri>.from(
      (manifest['files']! as List<Object?>).cast<String>().map<Uri>(
          (String path) =>
              Uri.file(globals.fs.path.join(flutterToolsAbsolutePath, path))),
    );
  }

  int _injectGradleWrapper(FlutterProject project) {
    int filesCreated = 0;
    copyDirectory(
      globals.cache.getArtifactDirectory('gradle_wrapper'),
      project.android.hostAppGradleRoot,
      onFileCopied: (File sourceFile, File destinationFile) {
        filesCreated++;
        final String modes = sourceFile.statSync().modeString();
        if (modes.contains('x')) {
          globals.os.makeExecutable(destinationFile);
        }
      },
    );
    return filesCreated;
  }
}

// A valid Dart identifier that can be used for a package, i.e. no
// capital letters.
// https://dart.dev/guides/language/language-tour#important-concepts
final RegExp _identifierRegExp = RegExp('[a-z_][a-z0-9_]*');

// non-contextual dart keywords.
//' https://dart.dev/guides/language/language-tour#keywords
const Set<String> _keywords = <String>{
  'abstract',
  'as',
  'assert',
  'async',
  'await',
  'break',
  'case',
  'catch',
  'class',
  'const',
  'continue',
  'covariant',
  'default',
  'deferred',
  'do',
  'dynamic',
  'else',
  'enum',
  'export',
  'extends',
  'extension',
  'external',
  'factory',
  'false',
  'final',
  'finally',
  'for',
  'function',
  'get',
  'hide',
  'if',
  'implements',
  'import',
  'in',
  'inout',
  'interface',
  'is',
  'late',
  'library',
  'mixin',
  'native',
  'new',
  'null',
  'of',
  'on',
  'operator',
  'out',
  'part',
  'patch',
  'required',
  'rethrow',
  'return',
  'set',
  'show',
  'source',
  'static',
  'super',
  'switch',
  'sync',
  'this',
  'throw',
  'true',
  'try',
  'typedef',
  'var',
  'void',
  'while',
  'with',
  'yield',
};

const Set<String> _packageDependencies = <String>{
  'collection',
  'flutter',
  'flutter_test',
  'meta',
};

/// Whether [name] is a valid Pub package.
@visibleForTesting
bool isValidPackageName(String name) {
  final Match? match = _identifierRegExp.matchAsPrefix(name);
  return match != null &&
      match.end == name.length &&
      !_keywords.contains(name);
}

// Return null if the project name is legal. Return a validation message if
// we should disallow the project name.
String? _validateProjectName(String projectName) {
  if (!isValidPackageName(projectName)) {
    return '"$projectName" is not a valid Dart package name.\n\n'
        'See https://dart.dev/tools/pub/pubspec#name for more information.';
  }
  if (_packageDependencies.contains(projectName)) {
    return "Invalid project name: '$projectName' - this will conflict with Flutter "
        'package dependencies.';
  }
  return null;
}
