// Copyright 2013 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:yaml/yaml.dart';

import 'base/file_system.dart';
import 'base/logger.dart';
import 'base/terminal.dart';

import 'result.dart';
import 'utils.dart';

const String _kMergedFilesKey = 'merged_files';
const String _kConflictFilesKey = 'conflict_files';
const String _kAddedFilesKey = 'added_files';
const String _kDeletedFilesKey = 'deleted_files';

/// Represents the manifest file that tracks the contents of the current
/// migration working directory.
///
/// This manifest file is created with the MigrateResult of a computeMigration run.
class MigrateManifest {
  /// Creates a new manifest from a MigrateResult.
  MigrateManifest({
    required this.migrateRootDir,
    required this.migrateResult,
  });

  /// Parses an existing migrate manifest.
  MigrateManifest.fromFile(File manifestFile)
      : migrateResult = MigrateResult.empty(),
        migrateRootDir = manifestFile.parent {
    final Object? yamlContents = loadYaml(manifestFile.readAsStringSync());
    if (yamlContents is! YamlMap) {
      throw Exception(
          'Invalid .migrate_manifest file in the migrate working directory. File is not a Yaml map.');
    }
    final YamlMap map = yamlContents;
    bool valid = map.containsKey(_kMergedFilesKey) &&
        map.containsKey(_kConflictFilesKey) &&
        map.containsKey(_kAddedFilesKey) &&
        map.containsKey(_kDeletedFilesKey);
    if (!valid) {
      throw Exception(
          'Invalid .migrate_manifest file in the migrate working directory. File is missing an entry.');
    }
    final Object? mergedFilesYaml = map[_kMergedFilesKey];
    final Object? conflictFilesYaml = map[_kConflictFilesKey];
    final Object? addedFilesYaml = map[_kAddedFilesKey];
    final Object? deletedFilesYaml = map[_kDeletedFilesKey];
    valid = valid && (mergedFilesYaml is YamlList || mergedFilesYaml == null);
    valid =
        valid && (conflictFilesYaml is YamlList || conflictFilesYaml == null);
    valid = valid && (addedFilesYaml is YamlList || addedFilesYaml == null);
    valid = valid && (deletedFilesYaml is YamlList || deletedFilesYaml == null);
    if (!valid) {
      throw Exception(
          'Invalid .migrate_manifest file in the migrate working directory. Entry is not a Yaml list.');
    }
    if (mergedFilesYaml != null) {
      for (final Object? localPath in mergedFilesYaml as YamlList) {
        if (localPath is String) {
          // We can fill the maps with partially dummy data as not all properties are used by the manifest.
          migrateResult.mergeResults.add(StringMergeResult.explicit(
              mergedString: '',
              hasConflict: false,
              exitCode: 0,
              localPath: localPath));
        }
      }
    }
    if (conflictFilesYaml != null) {
      for (final Object? localPath in conflictFilesYaml as YamlList) {
        if (localPath is String) {
          migrateResult.mergeResults.add(StringMergeResult.explicit(
              mergedString: '',
              hasConflict: true,
              exitCode: 1,
              localPath: localPath));
        }
      }
    }
    if (addedFilesYaml != null) {
      for (final Object? localPath in addedFilesYaml as YamlList) {
        if (localPath is String) {
          migrateResult.addedFiles.add(FilePendingMigration(
              localPath, migrateRootDir.childFile(localPath)));
        }
      }
    }
    if (deletedFilesYaml != null) {
      for (final Object? localPath in deletedFilesYaml as YamlList) {
        if (localPath is String) {
          migrateResult.deletedFiles.add(FilePendingMigration(
              localPath, migrateRootDir.childFile(localPath)));
        }
      }
    }
  }

  final Directory migrateRootDir;
  final MigrateResult migrateResult;

  /// A list of local paths of files that require conflict resolution.
  List<String> get conflictFiles {
    final List<String> output = <String>[];
    for (final MergeResult result in migrateResult.mergeResults) {
      if (result.hasConflict) {
        output.add(result.localPath);
      }
    }
    return output;
  }

  /// A list of local paths of files that require conflict resolution.
  List<String> remainingConflictFiles(Directory workingDir) {
    final List<String> output = <String>[];
    for (final String localPath in conflictFiles) {
      if (!_conflictsResolved(
          workingDir.childFile(localPath).readAsStringSync())) {
        output.add(localPath);
      }
    }
    return output;
  }

  // A list of local paths of files that had conflicts and are now fully resolved.
  List<String> resolvedConflictFiles(Directory workingDir) {
    final List<String> output = <String>[];
    for (final String localPath in conflictFiles) {
      if (_conflictsResolved(
          workingDir.childFile(localPath).readAsStringSync())) {
        output.add(localPath);
      }
    }
    return output;
  }

  /// A list of local paths of files that were automatically merged.
  List<String> get mergedFiles {
    final List<String> output = <String>[];
    for (final MergeResult result in migrateResult.mergeResults) {
      if (!result.hasConflict) {
        output.add(result.localPath);
      }
    }
    return output;
  }

  /// A list of local paths of files that were newly added.
  List<String> get addedFiles {
    final List<String> output = <String>[];
    for (final FilePendingMigration file in migrateResult.addedFiles) {
      output.add(file.localPath);
    }
    return output;
  }

  /// A list of local paths of files that are marked for deletion.
  List<String> get deletedFiles {
    final List<String> output = <String>[];
    for (final FilePendingMigration file in migrateResult.deletedFiles) {
      output.add(file.localPath);
    }
    return output;
  }

  /// Returns the manifest file given a migration workind directory.
  static File getManifestFileFromDirectory(Directory workingDir) {
    return workingDir.childFile('.migrate_manifest');
  }

  /// Writes the manifest yaml file in the working directory.
  void writeFile() {
    final StringBuffer mergedFileManifestContents = StringBuffer();
    final StringBuffer conflictFilesManifestContents = StringBuffer();
    for (final MergeResult result in migrateResult.mergeResults) {
      if (result.hasConflict) {
        conflictFilesManifestContents.write('  - ${result.localPath}\n');
      } else {
        mergedFileManifestContents.write('  - ${result.localPath}\n');
      }
    }

    final StringBuffer newFileManifestContents = StringBuffer();
    for (final String localPath in addedFiles) {
      newFileManifestContents.write('  - $localPath\n');
    }

    final StringBuffer deletedFileManifestContents = StringBuffer();
    for (final String localPath in deletedFiles) {
      deletedFileManifestContents.write('  - $localPath\n');
    }

    final String migrateManifestContents =
        'merged_files:\n${mergedFileManifestContents}conflict_files:\n${conflictFilesManifestContents}added_files:\n${newFileManifestContents}deleted_files:\n$deletedFileManifestContents';
    final File migrateManifest = getManifestFileFromDirectory(migrateRootDir);
    migrateManifest.createSync(recursive: true);
    migrateManifest.writeAsStringSync(migrateManifestContents, flush: true);
  }
}

/// Returns true if the file does not contain any git conflict markers.
bool _conflictsResolved(String contents) {
  if (contents.contains('>>>>>>>') &&
      contents.contains('=======') &&
      contents.contains('<<<<<<<')) {
    return false;
  }
  return true;
}

/// Returns true if the migration working directory has all conflicts resolved and prints the migration status.
///
/// The migration status printout lists all added, deleted, merged, and conflicted files.
bool checkAndPrintMigrateStatus(MigrateManifest manifest, Directory workingDir,
    {bool warnConflict = false, Logger? logger}) {
  final StringBuffer printout = StringBuffer();
  final StringBuffer redPrintout = StringBuffer();
  bool result = true;
  final List<String> remainingConflicts = <String>[];
  final List<String> mergedFiles = <String>[];
  for (final String localPath in manifest.conflictFiles) {
    if (!_conflictsResolved(
        workingDir.childFile(localPath).readAsStringSync())) {
      remainingConflicts.add(localPath);
    } else {
      mergedFiles.add(localPath);
    }
  }

  mergedFiles.addAll(manifest.mergedFiles);
  if (manifest.addedFiles.isNotEmpty) {
    printout.write('Added files:\n');
    for (final String localPath in manifest.addedFiles) {
      printout.write('  - $localPath\n');
    }
  }
  if (manifest.deletedFiles.isNotEmpty) {
    printout.write('Deleted files:\n');
    for (final String localPath in manifest.deletedFiles) {
      printout.write('  - $localPath\n');
    }
  }
  if (mergedFiles.isNotEmpty) {
    printout.write('Modified files:\n');
    for (final String localPath in mergedFiles) {
      printout.write('  - $localPath\n');
    }
  }
  if (remainingConflicts.isNotEmpty) {
    if (warnConflict) {
      printout.write(
          'Unable to apply migration. The following files in the migration working directory still have unresolved conflicts:');
    } else {
      printout.write('Merge conflicted files:');
    }
    for (final String localPath in remainingConflicts) {
      redPrintout.write('  - $localPath\n');
    }
    result = false;
  }
  if (logger != null) {
    logger.printStatus(printout.toString());
    logger.printStatus(redPrintout.toString(),
        color: TerminalColor.red, newline: false);
  }
  return result;
}
