// Copyright (c) 2014, 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 'utils.dart';
import 'version.dart';
import 'version_constraint.dart';
import 'version_union.dart';

/// Constrains versions to a fall within a given range.
///
/// If there is a minimum, then this only allows versions that are at that
/// minimum or greater. If there is a maximum, then only versions less than
/// that are allowed. In other words, this allows `>= min, < max`.
///
/// Version ranges are ordered first by their lower bounds, then by their upper
/// bounds. For example, `>=1.0.0 <2.0.0` is before `>=1.5.0 <2.0.0` is before
/// `>=1.5.0 <3.0.0`.
class VersionRange implements Comparable<VersionRange>, VersionConstraint {
  /// The minimum end of the range.
  ///
  /// If [includeMin] is `true`, this will be the minimum allowed version.
  /// Otherwise, it will be the highest version below the range that is not
  /// allowed.
  ///
  /// This may be `null` in which case the range has no minimum end and allows
  /// any version less than the maximum.
  final Version min;

  /// The maximum end of the range.
  ///
  /// If [includeMax] is `true`, this will be the maximum allowed version.
  /// Otherwise, it will be the lowest version above the range that is not
  /// allowed.
  ///
  /// This may be `null` in which case the range has no maximum end and allows
  /// any version greater than the minimum.
  final Version max;

  /// If `true` then [min] is allowed by the range.
  final bool includeMin;

  /// If `true`, then [max] is allowed by the range.
  final bool includeMax;

  /// Creates a new version range from [min] to [max], either inclusive or
  /// exclusive.
  ///
  /// If it is an error if [min] is greater than [max].
  ///
  /// Either [max] or [min] may be omitted to not clamp the range at that end.
  /// If both are omitted, the range allows all versions.
  ///
  /// If [includeMin] is `true`, then the minimum end of the range is inclusive.
  /// Likewise, passing [includeMax] as `true` makes the upper end inclusive.
  ///
  /// If [alwaysIncludeMaxPreRelease] is `true`, this will always include
  /// pre-release versions of an exclusive [max]. Otherwise, it will use the
  /// default behavior for pre-release versions of [max].
  factory VersionRange(
      {Version min,
      Version max,
      bool includeMin = false,
      bool includeMax = false,
      bool alwaysIncludeMaxPreRelease = false}) {
    if (min != null && max != null && min > max) {
      throw ArgumentError(
          'Minimum version ("$min") must be less than maximum ("$max").');
    }

    if (!alwaysIncludeMaxPreRelease &&
        !includeMax &&
        max != null &&
        !max.isPreRelease &&
        max.build.isEmpty &&
        (min == null ||
            !min.isPreRelease ||
            !equalsWithoutPreRelease(min, max))) {
      max = max.firstPreRelease;
    }

    return VersionRange._(min, max, includeMin, includeMax);
  }

  VersionRange._(this.min, this.max, this.includeMin, this.includeMax);

  @override
  bool operator ==(other) {
    if (other is! VersionRange) return false;

    return min == other.min &&
        max == other.max &&
        includeMin == other.includeMin &&
        includeMax == other.includeMax;
  }

  @override
  int get hashCode =>
      min.hashCode ^
      (max.hashCode * 3) ^
      (includeMin.hashCode * 5) ^
      (includeMax.hashCode * 7);

  @override
  bool get isEmpty => false;

  @override
  bool get isAny => min == null && max == null;

  /// Tests if [other] falls within this version range.
  @override
  bool allows(Version other) {
    if (min != null) {
      if (other < min) return false;
      if (!includeMin && other == min) return false;
    }

    if (max != null) {
      if (other > max) return false;
      if (!includeMax && other == max) return false;
    }

    return true;
  }

  @override
  bool allowsAll(VersionConstraint other) {
    if (other.isEmpty) return true;
    if (other is Version) return allows(other);

    if (other is VersionUnion) {
      return other.ranges.every(allowsAll);
    }

    if (other is VersionRange) {
      return !allowsLower(other, this) && !allowsHigher(other, this);
    }

    throw ArgumentError('Unknown VersionConstraint type $other.');
  }

  @override
  bool allowsAny(VersionConstraint other) {
    if (other.isEmpty) return false;
    if (other is Version) return allows(other);

    if (other is VersionUnion) {
      return other.ranges.any(allowsAny);
    }

    if (other is VersionRange) {
      return !strictlyLower(other, this) && !strictlyHigher(other, this);
    }

    throw ArgumentError('Unknown VersionConstraint type $other.');
  }

  @override
  VersionConstraint intersect(VersionConstraint other) {
    if (other.isEmpty) return other;
    if (other is VersionUnion) return other.intersect(this);

    // A range and a Version just yields the version if it's in the range.
    if (other is Version) {
      return allows(other) ? other : VersionConstraint.empty;
    }

    if (other is VersionRange) {
      // Intersect the two ranges.
      Version intersectMin;
      bool intersectIncludeMin;
      if (allowsLower(this, other)) {
        if (strictlyLower(this, other)) return VersionConstraint.empty;
        intersectMin = other.min;
        intersectIncludeMin = other.includeMin;
      } else {
        if (strictlyLower(other, this)) return VersionConstraint.empty;
        intersectMin = min;
        intersectIncludeMin = includeMin;
      }

      Version intersectMax;
      bool intersectIncludeMax;
      if (allowsHigher(this, other)) {
        intersectMax = other.max;
        intersectIncludeMax = other.includeMax;
      } else {
        intersectMax = max;
        intersectIncludeMax = includeMax;
      }

      if (intersectMin == null && intersectMax == null) {
        // Open range.
        return VersionRange();
      }

      // If the range is just a single version.
      if (intersectMin == intersectMax) {
        // Because we already verified that the lower range isn't strictly
        // lower, there must be some overlap.
        assert(intersectIncludeMin && intersectIncludeMax);
        return intersectMin;
      }

      // If we got here, there is an actual range.
      return VersionRange(
          min: intersectMin,
          max: intersectMax,
          includeMin: intersectIncludeMin,
          includeMax: intersectIncludeMax,
          alwaysIncludeMaxPreRelease: true);
    }

    throw ArgumentError('Unknown VersionConstraint type $other.');
  }

  @override
  VersionConstraint union(VersionConstraint other) {
    if (other is Version) {
      if (allows(other)) return this;

      if (other == min) {
        return VersionRange(
            min: min,
            max: max,
            includeMin: true,
            includeMax: includeMax,
            alwaysIncludeMaxPreRelease: true);
      }

      if (other == max) {
        return VersionRange(
            min: min,
            max: max,
            includeMin: includeMin,
            includeMax: true,
            alwaysIncludeMaxPreRelease: true);
      }

      return VersionConstraint.unionOf([this, other]);
    }

    if (other is VersionRange) {
      // If the two ranges don't overlap, we won't be able to create a single
      // VersionRange for both of them.
      var edgesTouch = (max == other.min && (includeMax || other.includeMin)) ||
          (min == other.max && (includeMin || other.includeMax));
      if (!edgesTouch && !allowsAny(other)) {
        return VersionConstraint.unionOf([this, other]);
      }

      Version unionMin;
      bool unionIncludeMin;
      if (allowsLower(this, other)) {
        unionMin = min;
        unionIncludeMin = includeMin;
      } else {
        unionMin = other.min;
        unionIncludeMin = other.includeMin;
      }

      Version unionMax;
      bool unionIncludeMax;
      if (allowsHigher(this, other)) {
        unionMax = max;
        unionIncludeMax = includeMax;
      } else {
        unionMax = other.max;
        unionIncludeMax = other.includeMax;
      }

      return VersionRange(
          min: unionMin,
          max: unionMax,
          includeMin: unionIncludeMin,
          includeMax: unionIncludeMax,
          alwaysIncludeMaxPreRelease: true);
    }

    return VersionConstraint.unionOf([this, other]);
  }

  @override
  VersionConstraint difference(VersionConstraint other) {
    if (other.isEmpty) return this;

    if (other is Version) {
      if (!allows(other)) return this;

      if (other == min) {
        if (!includeMin) return this;
        return VersionRange(
            min: min,
            max: max,
            includeMin: false,
            includeMax: includeMax,
            alwaysIncludeMaxPreRelease: true);
      }

      if (other == max) {
        if (!includeMax) return this;
        return VersionRange(
            min: min,
            max: max,
            includeMin: includeMin,
            includeMax: false,
            alwaysIncludeMaxPreRelease: true);
      }

      return VersionUnion.fromRanges([
        VersionRange(
            min: min,
            max: other,
            includeMin: includeMin,
            includeMax: false,
            alwaysIncludeMaxPreRelease: true),
        VersionRange(
            min: other,
            max: max,
            includeMin: false,
            includeMax: includeMax,
            alwaysIncludeMaxPreRelease: true)
      ]);
    } else if (other is VersionRange) {
      if (!allowsAny(other)) return this;

      VersionRange before;
      if (!allowsLower(this, other)) {
        before = null;
      } else if (min == other.min) {
        assert(includeMin && !other.includeMin);
        assert(min != null);
        before = min;
      } else {
        before = VersionRange(
            min: min,
            max: other.min,
            includeMin: includeMin,
            includeMax: !other.includeMin,
            alwaysIncludeMaxPreRelease: true);
      }

      VersionRange after;
      if (!allowsHigher(this, other)) {
        after = null;
      } else if (max == other.max) {
        assert(includeMax && !other.includeMax);
        assert(max != null);
        after = max;
      } else {
        after = VersionRange(
            min: other.max,
            max: max,
            includeMin: !other.includeMax,
            includeMax: includeMax,
            alwaysIncludeMaxPreRelease: true);
      }

      if (before == null && after == null) return VersionConstraint.empty;
      if (before == null) return after;
      if (after == null) return before;
      return VersionUnion.fromRanges([before, after]);
    } else if (other is VersionUnion) {
      var ranges = <VersionRange>[];
      var current = this;

      for (var range in other.ranges) {
        // Skip any ranges that are strictly lower than [current].
        if (strictlyLower(range, current)) continue;

        // If we reach a range strictly higher than [current], no more ranges
        // will be relevant so we can bail early.
        if (strictlyHigher(range, current)) break;

        var difference = current.difference(range);
        if (difference.isEmpty) {
          return VersionConstraint.empty;
        } else if (difference is VersionUnion) {
          // If [range] split [current] in half, we only need to continue
          // checking future ranges against the latter half.
          assert(difference.ranges.length == 2);
          ranges.add(difference.ranges.first);
          current = difference.ranges.last;
        } else {
          current = difference as VersionRange;
        }
      }

      if (ranges.isEmpty) return current;
      return VersionUnion.fromRanges(ranges..add(current));
    }

    throw ArgumentError('Unknown VersionConstraint type $other.');
  }

  @override
  int compareTo(VersionRange other) {
    if (min == null) {
      if (other.min == null) return _compareMax(other);
      return -1;
    } else if (other.min == null) {
      return 1;
    }

    var result = min.compareTo(other.min);
    if (result != 0) return result;
    if (includeMin != other.includeMin) return includeMin ? -1 : 1;

    return _compareMax(other);
  }

  /// Compares the maximum values of `this` and [other].
  int _compareMax(VersionRange other) {
    if (max == null) {
      if (other.max == null) return 0;
      return 1;
    } else if (other.max == null) {
      return -1;
    }

    var result = max.compareTo(other.max);
    if (result != 0) return result;
    if (includeMax != other.includeMax) return includeMax ? 1 : -1;
    return 0;
  }

  @override
  String toString() {
    var buffer = StringBuffer();

    if (min != null) {
      buffer..write(includeMin ? '>=' : '>')..write(min);
    }

    if (max != null) {
      if (min != null) buffer.write(' ');
      if (includeMax) {
        buffer..write('<=')..write(max);
      } else {
        buffer.write('<');
        if (max.isFirstPreRelease) {
          // Since `"<$max"` would parse the same as `"<$max-0"`, we just emit
          // `<$max` to avoid confusing "-0" suffixes.
          buffer.write('${max.major}.${max.minor}.${max.patch}');
        } else {
          buffer.write(max);

          // If `">=$min <$max"` would parse as `">=$min <$max-0"`, add `-*` to
          // indicate that actually does allow pre-release versions.
          var minIsPreReleaseOfMax = min != null &&
              min.isPreRelease &&
              equalsWithoutPreRelease(min, max);
          if (!max.isPreRelease && max.build.isEmpty && !minIsPreReleaseOfMax) {
            buffer.write('-∞');
          }
        }
      }
    }

    if (min == null && max == null) buffer.write('any');
    return buffer.toString();
  }
}

class CompatibleWithVersionRange extends VersionRange {
  CompatibleWithVersionRange(Version version)
      : super._(version, version.nextBreaking.firstPreRelease, true, false);

  @override
  String toString() => '^$min';
}
