// 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:async';
import 'dart:math';

import 'package:file/file.dart';

/// Performs a transactional update of a file in Google Cloud Storage.
///
/// It downloads the file, calls the [callback] to get the new contents, and
/// uploads the new contents. It uses generation IDs to ensure that the file
/// has not been modified between download and upload.
///
/// If the file is modified concurrently, it retries the operation up to
/// [maxRetries] times.
Future<void> transactionalUpdate({
  required String gsPath,
  required Future<String> Function(String currentContents) callback,
  required Future<String> Function(List<String> args) runGsUtil,
  required FileSystem fs,
  int maxRetries = 5,
  Directory? tempDirectory,
  bool dryRun = false,
}) async {
  if (dryRun) {
    print('Dry run: simulating update for $gsPath');
    final String newContents = await callback('');
    print('Resulting manifest content:\n$newContents');
    return;
  }

  final createTemp = tempDirectory == null;
  final Directory tempDir =
      tempDirectory ?? fs.systemTempDirectory.createTempSync('transactional_update.');

  try {
    await _transactionalUpdate(
      gsPath: gsPath,
      callback: callback,
      runGsUtil: runGsUtil,
      fs: fs,
      maxRetries: maxRetries,
      tempDir: tempDir,
    );
  } finally {
    if (createTemp) {
      try {
        tempDir.deleteSync(recursive: true);
      } catch (e) {
        print('Failed to delete temp directory ${tempDir.path}: $e');
      }
    }
  }
}

Future<void> _transactionalUpdate({
  required String gsPath,
  required Future<String> Function(String currentContents) callback,
  required Future<String> Function(List<String> args) runGsUtil,
  required FileSystem fs,
  required int maxRetries,
  required Directory tempDir,
}) async {
  final generationRegex = RegExp(r'Generation:\s+(\d+)');

  for (var attempt = 1; attempt <= maxRetries; attempt++) {
    print('Attempt $attempt of $maxRetries to update $gsPath');

    var generation = '0';
    var fileExists = true;

    try {
      final String statOutput = await runGsUtil(<String>['stat', gsPath]);
      final Match? match = generationRegex.firstMatch(statOutput);
      if (match == null) {
        throw Exception('Could not find generation ID in stat output:\n$statOutput');
      }
      generation = match.group(1)!;
    } catch (e) {
      print('Failed to stat $gsPath, assuming file does not exist: $e');
      fileExists = false;
      generation = '0';
    }

    final File localFile = fs.file(fs.path.join(tempDir.path, 'downloaded.json'));
    var contents = '';

    if (fileExists) {
      try {
        await runGsUtil(<String>['cp', '$gsPath#$generation', localFile.path]);
        contents = localFile.readAsStringSync();
      } catch (e) {
        print('Failed to download generation $generation of $gsPath: $e');
        if (attempt == maxRetries) {
          rethrow;
        }
        final int backoffMs = pow(2, attempt).toInt() * 1000;
        final int jitterMs = Random().nextInt(1000);
        await Future<void>.delayed(Duration(milliseconds: backoffMs + jitterMs));
        continue;
      }
    }

    final String newContents = await callback(contents);

    final File uploadFile = fs.file(fs.path.join(tempDir.path, 'upload.json'));
    uploadFile.writeAsStringSync(newContents);

    try {
      await runGsUtil(<String>[
        '-h',
        'x-goog-if-generation-match:$generation',
        'cp',
        uploadFile.path,
        gsPath,
      ]);
      print('Successfully updated $gsPath');
      return;
    } catch (e) {
      print('Failed to upload $gsPath with generation match $generation: $e');
      if (attempt == maxRetries) {
        rethrow;
      }
      final int backoffMs = pow(2, attempt).toInt() * 1000;
      final int jitterMs = Random().nextInt(1000);
      await Future<void>.delayed(Duration(milliseconds: backoffMs + jitterMs));
      continue;
    }
  }
  throw Exception('Failed to update $gsPath after $maxRetries attempts');
}
