// 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:convert';
import 'dart:io';
import 'dart:math' as math;

import 'package:image/image.dart';
import 'package:path/path.dart';

String authorizationToken;

class UploadError extends Error {
  UploadError(this.message);
  final String message;
  @override
  String toString() => 'UploadError($message)';
}

void logMessage(String s) { print(s); }

class Upload {
  Upload(this.fromPath, this.largeName, this.smallName);

  static math.Random random;
  static const String uriAuthority = 'www.googleapis.com';
  static const String uriPath = 'upload/storage/v1/b/flutter-catalog/o';

  final String fromPath;
  final String largeName;
  final String smallName;

  List<int> largeImage;
  List<int> smallImage;
  bool largeImageSaved = false;
  int retryCount = 0;
  bool isComplete = false;

  // Exponential backoff per https://cloud.google.com/storage/docs/exponential-backoff
  Duration get timeLimit {
    if (retryCount == 0)
      return const Duration(milliseconds: 1000);
    random ??= math.Random();
    return Duration(milliseconds: random.nextInt(1000) + (math.pow(2, retryCount) as int) * 1000);
  }

  Future<bool> save(HttpClient client, String name, List<int> content) async {
    try {
      final Uri uri = Uri.https(uriAuthority, uriPath, <String, String>{
        'uploadType': 'media',
        'name': name,
      });
      final HttpClientRequest request = await client.postUrl(uri);
      request
        ..headers.contentType = ContentType('image', 'png')
        ..headers.add('Authorization', 'Bearer $authorizationToken')
        ..add(content);

      final HttpClientResponse response = await request.close().timeout(timeLimit);
      if (response.statusCode == HttpStatus.ok) {
        logMessage('Saved $name');
        await response.drain<void>();
      } else {
        // TODO(hansmuller): only retry on 5xx and 429 responses
        logMessage('Request to save "$name" (length ${content.length}) failed with status ${response.statusCode}, will retry');
        logMessage(await response.cast<List<int>>().transform<String>(utf8.decoder).join());
      }
      return response.statusCode == HttpStatus.ok;
    } on TimeoutException catch (_) {
      logMessage('Request to save "$name" (length ${content.length}) timed out, will retry');
      return false;
    }
  }

  Future<bool> run(HttpClient client) async {
    assert(!isComplete);
    if (retryCount > 2)
      throw UploadError('upload of "$fromPath" to "$largeName" and "$smallName" failed after 2 retries');

    largeImage ??= await File(fromPath).readAsBytes();
    smallImage ??= encodePng(copyResize(decodePng(largeImage), width: 300));

    if (!largeImageSaved)
      largeImageSaved = await save(client, largeName, largeImage);
    isComplete = largeImageSaved && await save(client, smallName, smallImage);

    retryCount += 1;
    return isComplete;
  }

  static bool isNotComplete(Upload upload) => !upload.isComplete;
}

Future<void> saveScreenshots(List<String> fromPaths, List<String> largeNames, List<String> smallNames) async {
  assert(fromPaths.length == largeNames.length);
  assert(fromPaths.length == smallNames.length);

  List<Upload> uploads = List<Upload>(fromPaths.length);
  for (int index = 0; index < uploads.length; index += 1)
    uploads[index] = Upload(fromPaths[index], largeNames[index], smallNames[index]);

  while (uploads.any(Upload.isNotComplete)) {
    final HttpClient client = HttpClient();
    uploads = uploads.where(Upload.isNotComplete).toList();
    await Future.wait<bool>(uploads.map<Future<bool>>((Upload upload) => upload.run(client)));
    client.close(force: true);
  }
}


// If path is lib/foo.png then screenshotName is foo.
String screenshotName(String path) => basenameWithoutExtension(path);

Future<void> saveCatalogScreenshots({
    Directory directory, // Where the *.png screenshots are.
    String commit, // The commit hash to be used as a cloud storage "directory".
    String token, // Cloud storage authorization token.
    String prefix, // Prefix for all file names.
  }) async {
  final List<String> screenshots = <String>[
    for (final FileSystemEntity entity in directory.listSync())
      if (entity is File && entity.path.endsWith('.png'))
        entity.path,
  ];

  final List<String> largeNames = <String>[]; // Cloud storage names for the full res screenshots.
  final List<String> smallNames = <String>[]; // Likewise for the scaled down screenshots.
  for (final String path in screenshots) {
    final String name = screenshotName(path);
    largeNames.add('$commit/$prefix$name.png');
    smallNames.add('$commit/$prefix${name}_small.png');
  }

  authorizationToken = token;
  await saveScreenshots(screenshots, largeNames, smallNames);
}
