// 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.

// @dart = 2.8

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 '../cache.dart';
import '../convert.dart';
import '../dart/pub.dart';
import '../features.dart';
import '../flutter_project_metadata.dart';
import '../globals_null_migrated.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',
  'winuwp',
];

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',
      defaultsTo: false,
      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',
      negatable: true,
      defaultsTo: false,
      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',
      negatable: true,
      defaultsTo: false,
      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',
      defaultsTo: null,
      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 ObjectiveC (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,
    );
  }

  /// The output directory of the command.
  @protected
  Directory get projectDir {
    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,
      defaultsTo: <String>[
        ..._kAvailablePlatforms,
        if (featureFlags.isWindowsUwpEnabled)
          'winuwp',
      ],
      allowed: <String>[
        ..._kAvailablePlatforms,
        if (featureFlags.isWindowsUwpEnabled)
          'winuwp',
      ],
    );
  }

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

    if (argResults.rest.length > 1) {
      String message = 'Multiple output directories specified.';
      for (final String arg in argResults.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);
    if (projectMetadata.projectType != null) {
      return projectMetadata.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.');
      }
    }
    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) {
      case FileSystemEntityType.file:
        // Do not overwrite files.
        throwToolExit("Invalid project name: '$projectDirPath' - file exists.",
            exitCode: 2);
        break;
      case FileSystemEntityType.link:
        // Do not overwrite links.
        throwToolExit("Invalid project name: '$projectDirPath' - refers to a link.",
            exitCode: 2);
        break;
      default:
    }
  }

  /// 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({
    String organization,
    String projectName,
    String projectDescription,
    String androidLanguage,
    String iosLanguage,
    String flutterRoot,
    String dartSdkVersionBounds,
    bool withPluginHook = false,
    bool ios = false,
    bool android = false,
    bool web = false,
    bool linux = false,
    bool macos = false,
    bool windows = false,
    bool windowsUwp = 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 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,
      '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,
      'pluginClassCapitalSnakeCase': pluginClassCapitalSnakeCase,
      'pluginDartClass': pluginDartClass,
      // TODO(jonahwilliams): update after google3 uuid is updated.
      // ignore: prefer_const_constructors
      'pluginProjectUUID': Uuid().v4().toUpperCase(),
      'withPluginHook': withPluginHook,
      'androidLanguage': androidLanguage,
      'iosLanguage': iosLanguage,
      'flutterRevision': globals.flutterVersion.frameworkRevision,
      'flutterChannel': globals.flutterVersion.channel,
      'ios': ios,
      'android': android,
      'web': web,
      'linux': linux,
      'macos': macos,
      'windows': windows,
      'winuwp': windowsUwp,
      'year': DateTime.now().year,
      'dartSdkVersionBounds': dartSdkVersionBounds,
    };
  }

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

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

    if (boolArg('pub')) {
      await pub.get(
        context: PubContext.create,
        directory: directory.path,
        offline: boolArg('offline'),
        generateSyntheticPackage: false,
      );

      await project.ensureReadyForPlatformSpecificTooling(
        androidPlatform: templateContext['android'] as bool ?? false,
        iosPlatform: templateContext['ios'] as bool ?? false,
        linuxPlatform: templateContext['linux'] as bool ?? false,
        macOSPlatform: templateContext['macos'] as bool ?? false,
        windowsPlatform: templateContext['windows'] as bool ?? false,
        webPlatform: templateContext['web'] as bool ?? false,
        winUwpPlatform: templateContext['winuwp'] as bool ?? false,
      );
    }
    if (templateContext['android'] == true) {
      gradle.updateLocalProperties(project: project, requireAndroidSdk: false);
    }
    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('.');
  }

  Set<Uri> get _templateManifest =>
      __templateManifest ??= _computeTemplateManifest();
  Set<Uri> __templateManifest;
  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 != null && 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;
}
