// 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.

library pub_semver.src.version_range;

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`.
class VersionRange implements 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.
  VersionRange({this.min, this.max,
      this.includeMin: false, this.includeMax: false}) {
    if (min != null && max != null && min > max) {
      throw new ArgumentError(
          'Minimum version ("$min") must be less than maximum ("$max").');
    }
  }

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

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

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

  bool get isEmpty => false;

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

  /// Tests if [other] falls within this version range.
  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;

      // If the max isn't itself a pre-release, don't allow any pre-release
      // versions of the max.
      //
      // See: https://www.npmjs.org/doc/misc/semver.html
      if (!includeMax &&
          !max.isPreRelease && other.isPreRelease &&
          other.major == max.major && other.minor == max.minor &&
          other.patch == max.patch) {
        return false;
      }
    }

    return true;
  }

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

    if (other is VersionUnion) {
      return other.constraints.every((constraint) => allowsAll(constraint));
    }

    if (other is VersionRange) {
      if (min != null) {
        if (other.min == null) return false;
        if (min > other.min) return false;
        if (min == other.min && !includeMin && other.includeMin) return false;
      }

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

      return true;
    }

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

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

    if (other is VersionUnion) {
      return other.constraints.any((constraint) => allowsAny(constraint));
    }

    if (other is VersionRange) {
      // If neither range has a minimum, they'll overlap at some point.
      //
      //     ...     this     ]
      //     ...     other         ]
      if (min == null && other.min == null) return true;

      // If this range has a lower minimum than the other range, it overlaps as
      // long as its maximum is higher than or the same as the other range's
      // minimum.
      //
      //     [  this  ]            [  this  ]
      //        [  other  ]                 [  other  ]
      if (min == null || (other.min != null && min < other.min)) {
        if (max == null) return true;
        if (max > other.min) return true;
        if (max < other.min) return false;
        assert(max == other.min);
        return includeMax && other.includeMin;
      }

      // If this range has a higher minimum than the other range, it overlaps as
      // long as its minimum is lower than or the same as the other range's
      // maximum.
      //
      //         [  this  ]               [  this  ]
      //     [  other  ]        [  other  ]
      if (other.max == null) return true;
      if (min < other.max) return true;
      if (min > other.max) return false;
      assert(min == other.max);
      return includeMin && other.includeMax;
    }

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

  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.
      var intersectMin = min;
      var intersectIncludeMin = includeMin;
      var intersectMax = max;
      var intersectIncludeMax = includeMax;

      if (other.min == null) {
        // Do nothing.
      } else if (intersectMin == null || intersectMin < other.min) {
        intersectMin = other.min;
        intersectIncludeMin = other.includeMin;
      } else if (intersectMin == other.min && !other.includeMin) {
        // The edges are the same, but one is exclusive, make it exclusive.
        intersectIncludeMin = false;
      }

      if (other.max == null) {
        // Do nothing.
      } else if (intersectMax == null || intersectMax > other.max) {
        intersectMax = other.max;
        intersectIncludeMax = other.includeMax;
      } else if (intersectMax == other.max && !other.includeMax) {
        // The edges are the same, but one is exclusive, make it exclusive.
        intersectIncludeMax = false;
      }

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

      // If the range is just a single version.
      if (intersectMin == intersectMax) {
        // If both ends are inclusive, allow that version.
        if (intersectIncludeMin && intersectIncludeMax) return intersectMin;

        // Otherwise, no versions.
        return VersionConstraint.empty;
      }

      if (intersectMin != null && intersectMax != null &&
          intersectMin > intersectMax) {
        // Non-overlapping ranges, so empty.
        return VersionConstraint.empty;
      }

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

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

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

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

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

      return new 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 new VersionConstraint.unionOf([this, other]);
      }

      var unionMin = min;
      var unionIncludeMin = includeMin;
      var unionMax = max;
      var unionIncludeMax = includeMax;

      if (unionMin == null) {
        // Do nothing.
      } else if (other.min == null || other.min < min) {
        unionMin = other.min;
        unionIncludeMin = other.includeMin;
      } else if (min == other.min && other.includeMin) {
        // If the edges are the same but one is inclusive, make it inclusive.
        unionIncludeMin = true;
      }

      if (unionMax == null) {
        // Do nothing.
      } else if (other.max == null || other.max > max) {
        unionMax = other.max;
        unionIncludeMax = other.includeMax;
      } else if (max == other.max && other.includeMax) {
        // If the edges are the same but one is inclusive, make it inclusive.
        unionIncludeMax = true;
      }

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

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

  String toString() {
    var buffer = new StringBuffer();

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

    if (max != null) {
      if (min != null) buffer.write(' ');
      buffer.write(includeMax ? '<=' : '<');
      buffer.write(max);
    }

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