// Copyright (c) 2020, 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:async';

import 'package:pub_semver/pub_semver.dart';

import 'package_name.dart';
import 'pubspec.dart';
import 'source/hosted.dart';
import 'system_cache.dart';

/// Returns a new [Pubspec] without [original]'s dev_dependencies.
Pubspec stripDevDependencies(Pubspec original) {
  ArgumentError.checkNotNull(original, 'original');

  return Pubspec(
    original.name,
    version: original.version,
    sdkConstraints: original.sdkConstraints,
    dependencies: original.dependencies.values,
    devDependencies: [], // explicitly give empty list, to prevent lazy parsing
    dependencyOverrides: original.dependencyOverrides.values,
  );
}

/// Returns a new [Pubspec] without [original]'s dependency_overrides.
Pubspec stripDependencyOverrides(Pubspec original) {
  ArgumentError.checkNotNull(original, 'original');

  return Pubspec(
    original.name,
    version: original.version,
    sdkConstraints: original.sdkConstraints,
    dependencies: original.dependencies.values,
    devDependencies: original.devDependencies.values,
    dependencyOverrides: [],
  );
}

Future<Pubspec> constrainedToAtLeastNullSafetyPubspec(
    Pubspec original, SystemCache cache) async {
  /// Get the first version of [package] opting in to null-safety.
  Future<VersionConstraint> constrainToFirstWithNullSafety(
      PackageRange packageRange) async {
    final ref = packageRange.toRef();
    final available = await cache.getVersions(ref);
    if (available.isEmpty) {
      return stripUpperBound(packageRange.constraint);
    }

    available.sort((x, y) => x.version.compareTo(y.version));

    for (final p in available) {
      final pubspec = await cache.describe(p);
      if (pubspec.languageVersion.supportsNullSafety) {
        return VersionRange(min: p.version, includeMin: true);
      }
    }
    return stripUpperBound(packageRange.constraint);
  }

  Future<List<PackageRange>> allConstrainedToAtLeastNullSafety(
    Map<String, PackageRange> constrained,
  ) async {
    final result = await Future.wait(constrained.keys.map((name) async {
      final packageRange = constrained[name]!;
      var unconstrainedRange = packageRange;

      /// We only need to remove the upper bound if it is a hosted package.
      if (packageRange.description is HostedDescription) {
        unconstrainedRange = PackageRange(
          packageRange.toRef(),
          await constrainToFirstWithNullSafety(packageRange),
        );
      }
      return unconstrainedRange;
    }));

    return result;
  }

  final constrainedLists = await Future.wait([
    allConstrainedToAtLeastNullSafety(original.dependencies),
    allConstrainedToAtLeastNullSafety(original.devDependencies),
  ]);

  return Pubspec(
    original.name,
    version: original.version,
    sdkConstraints: original.sdkConstraints,
    dependencies: constrainedLists[0],
    devDependencies: constrainedLists[1],
    dependencyOverrides: original.dependencyOverrides.values,
  );
}

/// Returns new pubspec with the same dependencies as [original] but with the
/// upper bounds of the constraints removed.
///
/// If [stripOnly] is provided, only the packages whose names are in
/// [stripOnly] will have their upper bounds removed. If [stripOnly] is
/// not specified or empty, then all packages will have their upper bounds
/// removed.
Pubspec stripVersionUpperBounds(Pubspec original,
    {Iterable<String>? stripOnly}) {
  ArgumentError.checkNotNull(original, 'original');
  stripOnly ??= [];

  List<PackageRange> stripUpperBounds(
    Map<String, PackageRange> constrained,
  ) {
    final result = <PackageRange>[];

    for (final name in constrained.keys) {
      final packageRange = constrained[name]!;
      var unconstrainedRange = packageRange;

      if (stripOnly!.isEmpty || stripOnly.contains(packageRange.name)) {
        unconstrainedRange = PackageRange(
          packageRange.toRef(),
          stripUpperBound(packageRange.constraint),
        );
      }
      result.add(unconstrainedRange);
    }

    return result;
  }

  return Pubspec(
    original.name,
    version: original.version,
    sdkConstraints: original.sdkConstraints,
    dependencies: stripUpperBounds(original.dependencies),
    devDependencies: stripUpperBounds(original.devDependencies),
    dependencyOverrides: original.dependencyOverrides.values,
  );
}

/// Removes the upper bound of [constraint]. If [constraint] is the
/// empty version constraint, [VersionConstraint.empty] will be returned.
VersionConstraint stripUpperBound(VersionConstraint constraint) {
  ArgumentError.checkNotNull(constraint, 'constraint');

  /// A [VersionConstraint] has to either be a [VersionRange], [VersionUnion],
  /// or the empty [VersionConstraint].
  if (constraint is VersionRange) {
    return VersionRange(min: constraint.min, includeMin: constraint.includeMin);
  }

  if (constraint is VersionUnion) {
    if (constraint.ranges.isEmpty) return VersionConstraint.empty;

    final firstRange = constraint.ranges.first;
    return VersionRange(min: firstRange.min, includeMin: firstRange.includeMin);
  }

  assert(constraint == VersionConstraint.empty, 'unknown constraint type');

  /// If it gets here, [constraint] is the empty version constraint, so we
  /// just return an empty version constraint.
  return VersionConstraint.empty;
}
