// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. 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:convert';
import 'dart:io';

import 'package:collection/collection.dart';
import 'package:http/http.dart';
import 'package:pub_semver/pub_semver.dart';

import 'http.dart';
import 'log.dart';

String get flutterReleasesUrl =>
    Platform.environment['_PUB_TEST_FLUTTER_RELEASES_URL'] ??
    'https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json';

// Retrieves all released versions of Flutter.
Future<List<FlutterRelease>> _flutterReleases = () async {
  final response = await retryForHttp(
    'fetching available Flutter releases',
    () => globalHttpClient.fetch(Request('GET', Uri.parse(flutterReleasesUrl))),
  );
  final decoded = jsonDecode(response.body);
  if (decoded is! Map) throw FormatException('Bad response - should be a Map');
  final releases = decoded['releases'];
  if (releases is! List) {
    throw FormatException('Bad response - releases should be a list.');
  }
  final result = <FlutterRelease>[];
  for (final release in releases) {
    final channel = {
      'beta': Channel.beta,
      'stable': Channel.stable,
      'dev': Channel.dev,
    }[release['channel']];
    if (channel == null) throw FormatException('Release with bad channel');
    final dartVersion = release['dart_sdk_version'];
    // Some releases don't have an associated dart version, ignore.
    if (dartVersion is! String) continue;
    final flutterVersion = release['version'];
    if (flutterVersion is! String) throw FormatException('Not a string');
    result.add(
      FlutterRelease(
        flutterVersion: Version.parse(flutterVersion),
        dartVersion: Version.parse(dartVersion.split(' ').first),
        channel: channel,
      ),
    );
  }
  return result
      // Sort releases by channel and version.
      .sorted((a, b) {
        final compareChannels = b.channel.index - a.channel.index;
        if (compareChannels != 0) return compareChannels;
        return a.flutterVersion.compareTo(b.flutterVersion);
      })
      // Newest first.
      .reversed
      .toList();
}();

/// The "best" Flutter release for a given set of constraints is the first one
/// in [_flutterReleases] that matches both the flutter and dart constraint.
///
/// Returns if no such release could be found.
Future<FlutterRelease?> inferBestFlutterRelease(
  Map<String, VersionConstraint> sdkConstraints,
) async {
  final List<FlutterRelease> flutterReleases;
  try {
    flutterReleases = await _flutterReleases;
  } on Exception catch (e) {
    fine('Failed retrieving the list of flutter-releases: $e');
    return null;
  }
  return flutterReleases.firstWhereOrNull(
    (release) =>
        (sdkConstraints['flutter'] ?? VersionConstraint.any)
            .allows(release.flutterVersion) &&
        (sdkConstraints['dart'] ?? VersionConstraint.any)
            .allows(release.dartVersion),
  );
}

enum Channel {
  stable,
  beta,
  dev,
}

/// A version of the Flutter SDK and its related Dart SDK.
class FlutterRelease {
  final Version flutterVersion;
  final Version dartVersion;
  final Channel channel;
  FlutterRelease({
    required this.flutterVersion,
    required this.dartVersion,
    required this.channel,
  });
  @override
  String toString() =>
      'FlutterRelease(flutter=$flutterVersion, dart=$dartVersion, channel=$channel)';
}
