// 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 'dart:io' as io show Platform, exit, stderr, stdout;

import 'package:args/args.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:yaml/yaml.dart';
import 'package:yaml_edit/yaml_edit.dart';

/// The entry point for the version constraint bumping tool.
void main(List<String> arguments) {
  const FileSystem fileSystem = LocalFileSystem();
  final File script = fileSystem.file(io.Platform.script).absolute;
  final Directory flutterRoot = script.parent.parent.parent.parent;

  run(
    arguments,
    fileSystem: fileSystem,
    flutterRoot: flutterRoot,
    stdout: io.stdout,
    stderr: io.stderr,
    exit: io.exit,
  );
}

/// Runs the version constraint bumping tool with the given [arguments].
///
/// This is separated from [main] to allow for hermetic testing.
void run(
  List<String> arguments, {
  required FileSystem fileSystem,
  required Directory flutterRoot,
  required StringSink stdout,
  required StringSink stderr,
  required void Function(int) exit,
}) {
  final parser = ArgParser()
    ..addFlag('help', abbr: 'h', negatable: false, help: 'Print this usage information.');

  late final ArgResults options;
  try {
    options = parser.parse(arguments);
  } on FormatException catch (e) {
    stderr.writeln('ERROR: $e');
    _usage(parser, stderr, exit);
    return;
  }

  if (options['help'] as bool) {
    _usage(parser, stdout, exit, exitCode: 0);
    return;
  }

  if (options.rest.length != 2) {
    stderr.writeln(
      'ERROR: Expected exactly two arguments specifying the old SDK constraint and the new SDK constraint.',
    );
    _usage(parser, stderr, exit);
    return;
  }

  final String oldVersion = options.rest[0];
  final String newVersion = options.rest[1];

  var updatedCount = 0;
  var errorCount = 0;

  final (List<File> pubspecs, bool hasTraversalError) = _findPubspecs(flutterRoot, stderr);
  if (hasTraversalError) {
    errorCount++;
  }

  for (final file in pubspecs) {
    final String relativePath = fileSystem.path.relative(file.path, from: flutterRoot.path);
    try {
      final String content = file.readAsStringSync();
      final yamlEditor = YamlEditor(content);

      final YamlNode doc = loadYamlNode(content);
      if (doc is! YamlMap) {
        stderr.writeln('Error: $relativePath is not a valid YAML map.');
        errorCount++;
        continue;
      }

      var fileUpdated = false;
      if (doc.containsKey('environment')) {
        final Object? env = doc['environment'];
        if (env is YamlMap && env.containsKey('sdk')) {
          final Object? currentSdk = env['sdk'];
          if (currentSdk == newVersion) {
            // Already updated.
          } else if (currentSdk == oldVersion) {
            yamlEditor.update(<String>['environment', 'sdk'], newVersion);
            fileUpdated = true;
          } else {
            stdout.writeln(
              'Skipping $relativePath: SDK constraint "$currentSdk" does not match expected "$oldVersion".',
            );
          }
        }
      }

      if (fileUpdated) {
        var newContent = yamlEditor.toString();
        if (!newContent.endsWith('\n')) {
          newContent += '\n';
        }
        file.writeAsStringSync(newContent);
        stdout.writeln('Updated $relativePath');
        updatedCount++;
      }
    } catch (e) {
      stderr.writeln('Error updating $relativePath: $e');
      errorCount++;
    }
  }

  stdout.writeln('Done. Updated $updatedCount pubspec.yaml file${updatedCount == 1 ? '' : 's'}.');
  if (updatedCount == 0) {
    stderr.writeln('Error: No pubspec.yaml files were updated.');
    errorCount++;
  }
  if (errorCount > 0) {
    exit(1);
  }
}

(List<File>, bool) _findPubspecs(Directory dir, StringSink stderr) {
  final FileSystem fileSystem = dir.fileSystem;
  final result = <File>[];
  var hasError = false;
  void search(Directory currentDir) {
    try {
      for (final FileSystemEntity entity in currentDir.listSync(followLinks: false)) {
        if (entity is Directory) {
          final String name = fileSystem.path.basename(entity.path);
          if (name.startsWith('.') ||
              name == 'build' ||
              (name == 'cache' && fileSystem.path.basename(currentDir.path) == 'bin')) {
            continue;
          }
          search(entity);
        } else if (entity is File) {
          if (fileSystem.path.basename(entity.path) == 'pubspec.yaml') {
            result.add(entity);
          }
        }
      }
    } catch (e) {
      stderr.writeln('Error traversing ${currentDir.path}: $e');
      hasError = true;
    }
  }

  search(dir);
  return (result, hasError);
}

void _usage(ArgParser parser, StringSink out, void Function(int) exit, {int exitCode = 1}) {
  out.writeln(
    'Usage: dart dev/tools/bin/bump_version_constraints.dart <old_sdk_constraint> <new_sdk_constraint>',
  );
  out.writeln('Example: dart dev/tools/bin/bump_version_constraints.dart ^3.10.0-0 ^3.11.0-0');
  if (parser.options.isNotEmpty) {
    out.writeln();
    out.writeln('Options:');
    out.writeln(parser.usage);
  }
  exit(exitCode);
}
