// 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 'base/file_system.dart';
import 'base/logger.dart';
import 'flutter_project_metadata.dart';
import 'utils.dart';

/// Handles the custom/manual merging of one file at `localPath`.
///
/// The `merge` method should be overridden to implement custom merging.
abstract class CustomMerge {
  CustomMerge({
    required this.logger,
    required this.localPath,
  });

  /// The local path (with the project root as the root directory) of the file to merge.
  final String localPath;
  final Logger logger;

  /// Called to perform a custom three way merge between the current,
  /// base, and target files.
  MergeResult merge(File current, File base, File target);
}

/// Manually merges a flutter .metadata file.
///
/// See `FlutterProjectMetadata`.
class MetadataCustomMerge extends CustomMerge {
  MetadataCustomMerge({
    required super.logger,
  }) : super(localPath: '.metadata');

  @override
  MergeResult merge(File current, File base, File target) {
    final FlutterProjectMetadata result = computeMerge(
      FlutterProjectMetadata(current, logger),
      FlutterProjectMetadata(base, logger),
      FlutterProjectMetadata(target, logger),
      logger,
    );
    return StringMergeResult.explicit(
      mergedString: result.toString(),
      hasConflict: false,
      exitCode: 0,
      localPath: localPath,
    );
  }

  FlutterProjectMetadata computeMerge(
      FlutterProjectMetadata current,
      FlutterProjectMetadata base,
      FlutterProjectMetadata target,
      Logger logger) {
    // Prefer to update the version revision and channel to latest version.
    final String? versionRevision = target.versionRevision ??
        current.versionRevision ??
        base.versionRevision;
    final String? versionChannel =
        target.versionChannel ?? current.versionChannel ?? base.versionChannel;
    // Prefer to leave the project type untouched as it is non-trivial to change project type.
    final FlutterProjectType? projectType =
        current.projectType ?? base.projectType ?? target.projectType;
    final MigrateConfig migrateConfig = mergeMigrateConfig(
      current.migrateConfig,
      target.migrateConfig,
    );
    final FlutterProjectMetadata output = FlutterProjectMetadata.explicit(
      file: current.file,
      versionRevision: versionRevision,
      versionChannel: versionChannel,
      projectType: projectType,
      migrateConfig: migrateConfig,
      logger: logger,
    );
    return output;
  }

  MigrateConfig mergeMigrateConfig(
      MigrateConfig current, MigrateConfig target) {
    // Create the superset of current and target platforms with baseRevision updated to be that of target.
    final Map<FlutterProjectComponent, MigratePlatformConfig>
        projectComponentConfigs =
        <FlutterProjectComponent, MigratePlatformConfig>{};
    for (final MapEntry<FlutterProjectComponent, MigratePlatformConfig> entry
        in current.platformConfigs.entries) {
      if (target.platformConfigs.containsKey(entry.key)) {
        projectComponentConfigs[entry.key] = MigratePlatformConfig(
            component: entry.value.component,
            createRevision: entry.value.createRevision,
            baseRevision: target.platformConfigs[entry.key]?.baseRevision);
      } else {
        projectComponentConfigs[entry.key] = entry.value;
      }
    }
    for (final MapEntry<FlutterProjectComponent, MigratePlatformConfig> entry
        in target.platformConfigs.entries) {
      if (!projectComponentConfigs.containsKey(entry.key)) {
        projectComponentConfigs[entry.key] = entry.value;
      }
    }

    // Ignore the base file list.
    final List<String> unmanagedFiles =
        List<String>.from(current.unmanagedFiles);
    for (final String path in target.unmanagedFiles) {
      if (!unmanagedFiles.contains(path) &&
          !MigrateConfig.kDefaultUnmanagedFiles.contains(path)) {
        unmanagedFiles.add(path);
      }
    }
    return MigrateConfig(
      platformConfigs: projectComponentConfigs,
      unmanagedFiles: unmanagedFiles,
    );
  }
}
