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

import '../base/deferred_component.dart';
import '../base/error_handling_io.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../template.dart';
import 'deferred_components_validator.dart';

/// A class to configure and run deferred component setup verification checks
/// and tasks.
///
/// Once constructed, checks and tasks can be executed by calling the respective
/// methods. The results of the checks are stored internally and can be
/// displayed to the user by calling [displayResults].
class DeferredComponentsPrebuildValidator extends DeferredComponentsValidator {
  /// Constructs a validator instance.
  ///
  /// The [templatesDir] parameter is optional. If null, the tool's default
  /// templates directory will be used.
  ///
  /// When [exitOnFail] is set to true, the [handleResults] and [attemptToolExit]
  /// methods will exit the tool when this validator detects a recommended
  /// change. This defaults to true.
  DeferredComponentsPrebuildValidator(super.projectDir, super.logger, super.platform, {
    super.exitOnFail,
    super.title,
    Directory? templatesDir,
  }) : _templatesDir = templatesDir;

  final Directory? _templatesDir;

  /// Checks if an android dynamic feature module exists for each deferred
  /// component.
  ///
  /// Returns true if the check passed with no recommended changes, and false
  /// otherwise.
  ///
  /// This method looks for the existence of `android/<componentname>/build.gradle`
  /// and `android/<componentname>/src/main/AndroidManifest.xml`. If either of
  /// these files does not exist, it will generate it in the validator output
  /// directory based off of a template.
  ///
  /// This method does not check if the contents of either of the files are
  /// valid, as there are many ways that they can be validly configured.
  Future<bool> checkAndroidDynamicFeature(List<DeferredComponent> components) async {
    inputs.add(projectDir.childFile('pubspec.yaml'));
    if (components.isEmpty) {
      return false;
    }
    bool changesMade = false;
    for (final DeferredComponent component in components) {
      final _DeferredComponentAndroidFiles androidFiles = _DeferredComponentAndroidFiles(
        name: component.name,
        projectDir: projectDir,
        logger: logger,
        templatesDir: _templatesDir
      );
      if (!androidFiles.verifyFilesExist()) {
        // generate into temp directory
        final Map<String, List<File>> results = await androidFiles.generateFiles(
          alternateAndroidDir: outputDir,
          clearAlternateOutputDir: true,
        );
        if (results.containsKey('outputs')) {
          for (final File file in results['outputs']!) {
            generatedFiles.add(file.path);
            changesMade = true;
          }
          outputs.addAll(results['outputs']!);
        }
        if (results.containsKey('inputs')) {
          inputs.addAll(results['inputs']!);
        }
      }
    }
    return !changesMade;
  }

  /// Checks if the base module `app`'s `strings.xml` contain string
  /// resources for each component's name.
  ///
  /// Returns true if the check passed with no recommended changes, and false
  /// otherwise.
  ///
  /// In each dynamic feature module's AndroidManifest.xml, the
  /// name of the module is a string resource. This checks if
  /// the needed string resources are in the base module `strings.xml`.
  /// If not, this method will generate a modified `strings.xml` (or a
  /// completely new one if the original file did not exist) in the
  /// validator's output directory.
  ///
  /// For example, if there is a deferred component named `component1`,
  /// there should be the following string resource:
  ///
  ///   <string name="component1Name">component1</string>
  ///
  /// The string element's name attribute should be the component name with
  /// `Name` as a suffix, and the text contents should be the component name.
  bool checkAndroidResourcesStrings(List<DeferredComponent> components) {
    final Directory androidDir = projectDir.childDirectory('android');
    inputs.add(projectDir.childFile('pubspec.yaml'));

    // Add component name mapping to strings.xml
    final File stringRes = androidDir
      .childDirectory('app')
      .childDirectory('src')
      .childDirectory('main')
      .childDirectory('res')
      .childDirectory('values')
      .childFile('strings.xml');
    inputs.add(stringRes);
    final File stringResOutput = outputDir
      .childDirectory('app')
      .childDirectory('src')
      .childDirectory('main')
      .childDirectory('res')
      .childDirectory('values')
      .childFile('strings.xml');
    ErrorHandlingFileSystem.deleteIfExists(stringResOutput);
    if (components.isEmpty) {
      return true;
    }
    final Map<String, String> requiredEntriesMap  = <String, String>{};
    for (final DeferredComponent component in components) {
      requiredEntriesMap['${component.name}Name'] = component.name;
    }
    if (stringRes.existsSync()) {
      bool modified = false;
      XmlDocument document;
      try {
        document = XmlDocument.parse(stringRes.readAsStringSync());
      } on XmlException {
        invalidFiles[stringRes.path] = 'Error parsing $stringRes '
        'Please ensure that the strings.xml is a valid XML document and '
        'try again.';
        return false;
      }
      // Check if all required lines are present, and fix if name exists, but
      // wrong string stored.
      for (final XmlElement resources in document.findAllElements('resources')) {
        for (final XmlElement element in resources.findElements('string')) {
          final String? name = element.getAttribute('name');
          if (requiredEntriesMap.containsKey(name)) {
            if (element.innerText != requiredEntriesMap[name]) {
              element.innerText = requiredEntriesMap[name]!;
              modified = true;
            }
            requiredEntriesMap.remove(name);
          }
        }
        requiredEntriesMap.forEach((String key, String value) {
          modified = true;
          final XmlElement newStringElement = XmlElement(
            XmlName.fromString('string'),
            <XmlAttribute>[
              XmlAttribute(XmlName.fromString('name'), key),
            ],
            <XmlNode>[
              XmlText(value),
            ],
          );
          resources.children.add(newStringElement);
        });
        break;
      }
      if (modified) {
        stringResOutput.createSync(recursive: true);
        stringResOutput.writeAsStringSync(document.toXmlString(pretty: true));
        modifiedFiles.add(stringResOutput.path);
        return false;
      }
      return true;
    }
    // strings.xml does not exist, generate completely new file.
    stringResOutput.createSync(recursive: true);
    final StringBuffer buffer = StringBuffer();
    buffer.writeln('''
<?xml version="1.0" encoding="utf-8"?>
<resources>
''');
    for (final String key in requiredEntriesMap.keys) {
      buffer.write('    <string name="$key">${requiredEntriesMap[key]}</string>\n');
    }
    buffer.write(
'''
</resources>

''');
    stringResOutput.writeAsStringSync(buffer.toString(), flush: true, mode: FileMode.append);
    generatedFiles.add(stringResOutput.path);
    return false;
  }

  /// Deletes all files inside of the validator's output directory.
  void clearOutputDir() {
    final Directory dir = projectDir.childDirectory('build').childDirectory(DeferredComponentsValidator.kDeferredComponentsTempDirectory);
    ErrorHandlingFileSystem.deleteIfExists(dir, recursive: true);
  }
}

// Handles a single deferred component's android dynamic feature module
// directory.
class _DeferredComponentAndroidFiles {
  _DeferredComponentAndroidFiles({
    required this.name,
    required this.projectDir,
    required this.logger,
    Directory? templatesDir,
  }) : _templatesDir = templatesDir;

  // The name of the deferred component.
  final String name;
  final Directory projectDir;
  final Logger logger;
  final Directory? _templatesDir;

  Directory get androidDir => projectDir.childDirectory('android');
  Directory get componentDir => androidDir.childDirectory(name);

  File get androidManifestFile => componentDir.childDirectory('src').childDirectory('main').childFile('AndroidManifest.xml');
  File get buildGradleFile {
    if (componentDir.childFile('build.gradle').existsSync()) {
      return componentDir.childFile('build.gradle');
    }
    return componentDir.childFile('build.gradle.kts');
  }

  // True when AndroidManifest.xml and build.gradle/build.gradle.kts exist for
  // the android dynamic feature.
  bool verifyFilesExist() {
    return androidManifestFile.existsSync() && buildGradleFile.existsSync();
  }

  // Generates any missing basic files for the dynamic feature into a temporary directory.
  Future<Map<String, List<File>>> generateFiles({Directory? alternateAndroidDir, bool clearAlternateOutputDir = false}) async {
    final Directory outputDir = alternateAndroidDir?.childDirectory(name) ?? componentDir;
    if (clearAlternateOutputDir && alternateAndroidDir != null) {
      ErrorHandlingFileSystem.deleteIfExists(outputDir);
    }
    final List<File> inputs = <File>[];
    inputs.add(androidManifestFile);
    inputs.add(buildGradleFile);
    final Map<String, List<File>> results = <String, List<File>>{'inputs': inputs};
    results['outputs'] = await _setupComponentFiles(outputDir);
    return results;
  }

  // generates default build.gradle and AndroidManifest.xml for the deferred component.
  Future<List<File>> _setupComponentFiles(Directory outputDir) async {
    Template template;
    final Directory? templatesDir = _templatesDir;
    if (templatesDir != null) {
      final Directory templateComponentDir = templatesDir.childDirectory('module${globals.fs.path.separator}android${globals.fs.path.separator}deferred_component');
      template = Template(templateComponentDir, templateComponentDir,
        fileSystem: globals.fs,
        logger: logger,
        templateRenderer: globals.templateRenderer,
      );
    } else {
      template = await Template.fromName('module${globals.fs.path.separator}android${globals.fs.path.separator}deferred_component',
        fileSystem: globals.fs,
        templateManifest: null,
        logger: logger,
        templateRenderer: globals.templateRenderer,
      );
    }
    final Map<String, Object> context = <String, Object>{
      'androidIdentifier': FlutterProject.current().manifest.androidPackage ?? 'com.example.${FlutterProject.current().manifest.appName}',
      'componentName': name,
    };

    template.render(outputDir, context);

    final List<File> generatedFiles = <File>[];

    final File tempBuildGradle = outputDir.childFile('build.gradle');
    if (!buildGradleFile.existsSync()) {
      generatedFiles.add(tempBuildGradle);
    } else {
      ErrorHandlingFileSystem.deleteIfExists(tempBuildGradle);
    }
    final File tempAndroidManifest = outputDir
      .childDirectory('src')
      .childDirectory('main')
      .childFile('AndroidManifest.xml');
    if (!androidManifestFile.existsSync()) {
      generatedFiles.add(tempAndroidManifest);
    } else {
      ErrorHandlingFileSystem.deleteIfExists(tempAndroidManifest);
    }
    return generatedFiles;
  }
}
