// 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:file/file.dart';
import 'package:package_config/package_config.dart';
import 'package:package_config/package_config_types.dart';

import 'base/common.dart';
import 'base/context.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
import 'base/template.dart';
import 'cache.dart';
import 'dart/package_map.dart';

/// The Kotlin keywords which are not Java keywords.
/// They are escaped in Kotlin files.
///
/// https://kotlinlang.org/docs/keyword-reference.html
const List<String> kReservedKotlinKeywords = <String>['when', 'in', 'is'];

/// Provides the path where templates used by flutter_tools are stored.
class TemplatePathProvider {
  const TemplatePathProvider();

  /// Returns the directory containing the 'name' template directory.
  Directory directoryInPackage(String name, FileSystem fileSystem) {
    final String templatesDir = fileSystem.path.join(Cache.flutterRoot!,
        'packages', 'flutter_tools', 'templates');
    return fileSystem.directory(fileSystem.path.join(templatesDir, name));
  }

  /// Returns the directory containing the 'name' template directory in
  /// flutter_template_images, to resolve image placeholder against.
  /// if 'name' is null, return the parent template directory.
  Future<Directory> imageDirectory(String? name, FileSystem fileSystem, Logger logger) async {
    final String toolPackagePath = fileSystem.path.join(
        Cache.flutterRoot!, 'packages', 'flutter_tools');
    final String packageFilePath = fileSystem.path.join(toolPackagePath, '.dart_tool', 'package_config.json');
    final PackageConfig packageConfig = await loadPackageConfigWithLogging(
      fileSystem.file(packageFilePath),
      logger: logger,
    );
    final Uri? imagePackageLibDir = packageConfig['flutter_template_images']?.packageUriRoot;
    final Directory templateDirectory = fileSystem.directory(imagePackageLibDir)
        .parent
        .childDirectory('templates');
    return name == null ? templateDirectory : templateDirectory.childDirectory(name);
  }
}

TemplatePathProvider get templatePathProvider => context.get<TemplatePathProvider>() ?? const TemplatePathProvider();

/// Expands templates in a directory to a destination. All files that must
/// undergo template expansion should end with the '.tmpl' extension. All files
/// that should be replaced with the corresponding image from
/// flutter_template_images should end with the '.img.tmpl' extension. All other
/// files are ignored. In case the contents of entire directories must be copied
/// as is, the directory itself can end with '.tmpl' extension. Files within
/// such a directory may also contain the '.tmpl' or '.img.tmpl' extensions and
/// will be considered for expansion. In case certain files need to be copied
/// but without template expansion (data files, etc.), the '.copy.tmpl'
/// extension may be used. Furthermore, templates may contain additional
/// test files intended to run on the CI. Test files must end in `.test.tmpl`
/// and are only included when the --implementation-tests flag is enabled.
///
/// Folders with platform/language-specific content must be named
/// '<platform>-<language>.tmpl'.
///
/// Files in the destination will contain none of the '.tmpl', '.copy.tmpl',
/// 'img.tmpl', or '-<language>.tmpl' extensions.
class Template {
  factory Template(Directory templateSource, Directory? imageSourceDir, {
    required FileSystem fileSystem,
    required Logger logger,
    required TemplateRenderer templateRenderer,
    Set<Uri>? templateManifest,
  }) {
    return Template._(
      <Directory>[templateSource],
      imageSourceDir != null ? <Directory>[imageSourceDir] : <Directory>[],
      fileSystem: fileSystem,
      logger: logger,
      templateRenderer: templateRenderer,
      templateManifest: templateManifest,
    );
  }

  Template._(
    List<Directory> templateSources, this.imageSourceDirectories, {
    required FileSystem fileSystem,
    required Logger logger,
    required TemplateRenderer templateRenderer,
    required Set<Uri>? templateManifest,
  }) : _fileSystem = fileSystem,
       _logger = logger,
       _templateRenderer = templateRenderer,
       _templateManifest = templateManifest ?? <Uri>{} {
    for (final Directory sourceDirectory in templateSources) {
      if (!sourceDirectory.existsSync()) {
        throwToolExit('Template source directory does not exist: ${sourceDirectory.absolute.path}');
      }
    }

    final Map<FileSystemEntity, Directory> templateFiles = <FileSystemEntity, Directory>{
      for (final Directory sourceDirectory in templateSources)
        for (final FileSystemEntity entity in sourceDirectory.listSync(recursive: true))
          entity: sourceDirectory,
    };
    for (final FileSystemEntity entity in templateFiles.keys.whereType<File>()) {
      if (_templateManifest.isNotEmpty && !_templateManifest.contains(Uri.file(entity.absolute.path))) {
        _logger.printTrace('Skipping ${entity.absolute.path}, missing from the template manifest.');
        // Skip stale files in the flutter_tools directory.
        continue;
      }

      final String relativePath = fileSystem.path.relative(entity.path,
          from: templateFiles[entity]!.absolute.path);
      if (relativePath.contains(templateExtension)) {
        // If '.tmpl' appears anywhere within the path of this entity, it is
        // a candidate for rendering. This catches cases where the folder
        // itself is a template.
        _templateFilePaths[relativePath] = fileSystem.path.absolute(entity.path);
      }
    }
  }

  static Future<Template> fromName(String name, {
    required FileSystem fileSystem,
    required Set<Uri>? templateManifest,
    required Logger logger,
    required TemplateRenderer templateRenderer,
  }) async {
    // All named templates are placed in the 'templates' directory
    final Directory templateDir = templatePathProvider.directoryInPackage(name, fileSystem);
    final Directory imageDir = await templatePathProvider.imageDirectory(name, fileSystem, logger);
    return Template._(
      <Directory>[templateDir],
      <Directory>[imageDir],
      fileSystem: fileSystem,
      logger: logger,
      templateRenderer: templateRenderer,
      templateManifest: templateManifest,
    );
  }

  static Future<Template> merged(List<String> names, Directory directory, {
    required FileSystem fileSystem,
    required Set<Uri> templateManifest,
    required Logger logger,
    required TemplateRenderer templateRenderer,
  }) async {
    // All named templates are placed in the 'templates' directory
    return Template._(
      <Directory>[
        for (final String name in names)
          templatePathProvider.directoryInPackage(name, fileSystem),
      ],
      <Directory>[
        for (final String name in names)
          if ((await templatePathProvider.imageDirectory(name, fileSystem, logger)).existsSync())
            await templatePathProvider.imageDirectory(name, fileSystem, logger),
      ],
      fileSystem: fileSystem,
      logger: logger,
      templateRenderer: templateRenderer,
      templateManifest: templateManifest,
    );
  }

  final FileSystem _fileSystem;
  final Logger _logger;
  final Set<Uri> _templateManifest;
  final TemplateRenderer _templateRenderer;

  static const String templateExtension = '.tmpl';
  static const String copyTemplateExtension = '.copy.tmpl';
  static const String imageTemplateExtension = '.img.tmpl';
  static const String testTemplateExtension = '.test.tmpl';
  final Pattern _kTemplateLanguageVariant = RegExp(r'(\w+)-(\w+)\.tmpl.*');
  final List<Directory> imageSourceDirectories;

  final Map<String /* relative */, String /* absolute source */> _templateFilePaths = <String, String>{};

  /// Render the template into [directory].
  ///
  /// May throw a [ToolExit] if the directory is not writable.
  int render(
    Directory destination,
    Map<String, Object?> context, {
    bool overwriteExisting = true,
    bool printStatusWhenWriting = true,
  }) {
    try {
      destination.createSync(recursive: true);
    } on FileSystemException catch (err) {
      _logger.printError(err.toString());
      throwToolExit('Failed to flutter create at ${destination.path}.');
    }
    int fileCount = 0;
    final bool implementationTests = (context['implementationTests'] as bool?) ?? false;

    /// Returns the resolved destination path corresponding to the specified
    /// raw destination path, after performing language filtering and template
    /// expansion on the path itself.
    ///
    /// Returns null if the given raw destination path has been filtered.
    String? renderPath(String relativeDestinationPath) {
      final Match? match = _kTemplateLanguageVariant.matchAsPrefix(relativeDestinationPath);
      if (match != null) {
        final String platform = match.group(1)!;
        final String? language = context['${platform}Language'] as String?;
        if (language != match.group(2)) {
          return null;
        }
        relativeDestinationPath = relativeDestinationPath.replaceAll('$platform-$language.tmpl', platform);
      }

      final bool android = (context['android'] as bool?) ?? false;
      if (relativeDestinationPath.contains('android') && !android) {
        return null;
      }

      final bool ios = (context['ios'] as bool?) ?? false;
      if (relativeDestinationPath.contains('ios') && !ios) {
        return null;
      }

      // Only build a web project if explicitly asked.
      final bool web = (context['web'] as bool?) ?? false;
      if (relativeDestinationPath.contains('web') && !web) {
        return null;
      }
      // Only build a Linux project if explicitly asked.
      final bool linux = (context['linux'] as bool?) ?? false;
      if (relativeDestinationPath.startsWith('linux.tmpl') && !linux) {
        return null;
      }
      // Only build a macOS project if explicitly asked.
      final bool macOS = (context['macos'] as bool?) ?? false;
      if (relativeDestinationPath.startsWith('macos.tmpl') && !macOS) {
        return null;
      }
      // Only build a Windows project if explicitly asked.
      final bool windows = (context['windows'] as bool?) ?? false;
      if (relativeDestinationPath.startsWith('windows.tmpl') && !windows) {
        return null;
      }

      final String? projectName = context['projectName'] as String?;
      final String? androidIdentifier = context['androidIdentifier'] as String?;
      final String? pluginClass = context['pluginClass'] as String?;
      final String? pluginClassSnakeCase = context['pluginClassSnakeCase'] as String?;
      final String destinationDirPath = destination.absolute.path;
      final String pathSeparator = _fileSystem.path.separator;
      String finalDestinationPath = _fileSystem.path
        .join(destinationDirPath, relativeDestinationPath)
        .replaceAll(copyTemplateExtension, '')
        .replaceAll(imageTemplateExtension, '')
        .replaceAll(testTemplateExtension, '')
        .replaceAll(templateExtension, '');

      if (android && androidIdentifier != null) {
        finalDestinationPath = finalDestinationPath
            .replaceAll('androidIdentifier', androidIdentifier.replaceAll('.', pathSeparator));
      }
      if (projectName != null) {
        finalDestinationPath = finalDestinationPath.replaceAll('projectName', projectName);
      }
      // This must be before the pluginClass replacement step.
      if (pluginClassSnakeCase != null) {
        finalDestinationPath = finalDestinationPath.replaceAll('pluginClassSnakeCase', pluginClassSnakeCase);
      }
      if (pluginClass != null) {
        finalDestinationPath = finalDestinationPath.replaceAll('pluginClass', pluginClass);
      }
      return finalDestinationPath;
    }

    _templateFilePaths.forEach((String relativeDestinationPath, String absoluteSourcePath) {
      final bool withRootModule = context['withRootModule'] as bool? ?? false;
      if (!withRootModule && absoluteSourcePath.contains('flutter_root')) {
        return;
      }

      if (!implementationTests && absoluteSourcePath.contains(testTemplateExtension)) {
        return;
      }

      final String? finalDestinationPath = renderPath(relativeDestinationPath);
      if (finalDestinationPath == null) {
        return;
      }
      final File finalDestinationFile = _fileSystem.file(finalDestinationPath);
      final String relativePathForLogging = _fileSystem.path.relative(finalDestinationFile.path);

      // Step 1: Check if the file needs to be overwritten.

      if (finalDestinationFile.existsSync()) {
        if (overwriteExisting) {
          finalDestinationFile.deleteSync(recursive: true);
          if (printStatusWhenWriting) {
            _logger.printStatus('  $relativePathForLogging (overwritten)');
          }
        } else {
          // The file exists but we cannot overwrite it, move on.
          if (printStatusWhenWriting) {
            _logger.printTrace('  $relativePathForLogging (existing - skipped)');
          }
          return;
        }
      } else {
        if (printStatusWhenWriting) {
          _logger.printStatus('  $relativePathForLogging (created)');
        }
      }

      fileCount += 1;

      finalDestinationFile.createSync(recursive: true);
      final File sourceFile = _fileSystem.file(absoluteSourcePath);

      // Step 2: If the absolute paths ends with a '.copy.tmpl', this file does
      //         not need mustache rendering but needs to be directly copied.

      if (sourceFile.path.endsWith(copyTemplateExtension)) {
        sourceFile.copySync(finalDestinationFile.path);

        return;
      }

      // Step 3: If the absolute paths ends with a '.img.tmpl', this file needs
      //         to be copied from the template image package.

      if (sourceFile.path.endsWith(imageTemplateExtension)) {
        final List<File> potentials = <File>[
          for (final Directory imageSourceDir in imageSourceDirectories)
            _fileSystem.file(_fileSystem.path
                .join(imageSourceDir.path, relativeDestinationPath.replaceAll(imageTemplateExtension, ''))),
        ];

        if (potentials.any((File file) => file.existsSync())) {
          final File imageSourceFile = potentials.firstWhere((File file) => file.existsSync());

          imageSourceFile.copySync(finalDestinationFile.path);
        } else {
          throwToolExit('Image File not found ${finalDestinationFile.path}');
        }

        return;
      }

      // Step 4: If the absolute path ends with a '.tmpl', this file needs
      //         rendering via mustache.

      if (sourceFile.path.endsWith(templateExtension)) {
        final String templateContents = sourceFile.readAsStringSync();
        final String? androidIdentifier = context['androidIdentifier'] as String?;
        if (finalDestinationFile.path.endsWith('.kt') && androidIdentifier != null) {
          context['androidIdentifier'] = _escapeKotlinKeywords(androidIdentifier);
        }

        // Use a copy of the context,
        // since the original is used in rendering other templates.
        final Map<String, Object?> localContext = finalDestinationFile.path.endsWith('.yaml')
          ? _createEscapedContextCopy(context)
          : context;

        final String renderedContents = _templateRenderer.renderString(templateContents, localContext);

        finalDestinationFile.writeAsStringSync(renderedContents);

        return;
      }

      // Step 5: This file does not end in .tmpl but is in a directory that
      //         does. Directly copy the file to the destination.
      sourceFile.copySync(finalDestinationFile.path);
    });

    return fileCount;
  }
}

/// Create a copy of the given [context], escaping its values when necessary.
///
/// Returns the copied context.
Map<String, Object?> _createEscapedContextCopy(Map<String, Object?> context) {
  final Map<String, Object?> localContext = Map<String, Object?>.of(context);

  final String? description = localContext['description'] as String?;

  if (description != null && description.isNotEmpty) {
    localContext['description'] = escapeYamlString(description);
  }

  return localContext;
}

String _escapeKotlinKeywords(String androidIdentifier) {
  final List<String> segments = androidIdentifier.split('.');
  final List<String> correctedSegments = segments.map(
    (String segment) => kReservedKotlinKeywords.contains(segment) ? '`$segment`' : segment
  ).toList();
  return correctedSegments.join('.');
}

String escapeYamlString(String value) {
  final StringBuffer result = StringBuffer();
  result.write('"');
  for (final int rune in value.runes) {
    result.write(
      switch (rune) {
        0x00 => r'\0',
        0x09 => r'\t',
        0x0A => r'\n',
        0x0D => r'\r',
        0x22 => r'\"',
        0x5C => r'\\',
        < 0x20 => '\\x${rune.toRadixString(16).padLeft(2, "0")}',
        _ => String.fromCharCode(rune),
      }
    );
  }
  result.write('"');
  return result.toString();
}
