// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.

import type { Comparator, Range, SemVer } from "./types.ts";
import { testComparatorSet } from "./_test_comparator_set.ts";
import { isWildcardComparator } from "./_shared.ts";
import { compare } from "./compare.ts";

/**
 * Check if the SemVer is less than the range.
 *
 * @example Usage
 * ```ts
 * import { parse, parseRange, lessThanRange } from "@std/semver";
 * import { assert, assertFalse } from "@std/assert";
 *
 * const v0 = parse("1.2.3");
 * const v1 = parse("1.0.0");
 * const range = parseRange(">=1.2.3 <1.2.4");
 * assertFalse(lessThanRange(v0, range));
 * assert(lessThanRange(v1, range));
 * ```
 *
 * @param semver The version to check.
 * @param range The range to check against.
 * @returns `true` if the SemVer is less than the range, `false` otherwise.
 */
export function lessThanRange(semver: SemVer, range: Range): boolean {
  return range.every((comparatorSet) =>
    lessThanComparatorSet(semver, comparatorSet)
  );
}

function lessThanComparatorSet(semver: SemVer, comparatorSet: Comparator[]) {
  // If the comparator set contains wildcard, then the semver is not greater than the range.
  if (comparatorSet.some(isWildcardComparator)) return false;
  // If the SemVer satisfies the comparator set, then it's not less than the range.
  if (testComparatorSet(semver, comparatorSet)) return false;
  // If the SemVer is greater than any of the comparator set, then it's not less than the range.
  if (
    comparatorSet.some((comparator) =>
      greaterThanComparator(semver, comparator)
    )
  ) return false;
  return true;
}

function greaterThanComparator(
  semver: SemVer,
  comparator: Comparator,
): boolean {
  const cmp = compare(semver, comparator);
  switch (comparator.operator) {
    case "=":
    case undefined:
      return cmp > 0;
    case "!=":
      return false;
    case ">":
      return false;
    case "<":
      return cmp >= 0;
    case ">=":
      return false;
    case "<=":
      return cmp > 0;
  }
}

// denoCacheMetadata={"headers":{"cache-control":"public, max-age=31536000, immutable","cross-origin-resource-policy":"cross-origin","set-cookie":"__cf_bm=aYp_QiD3K.IishFYGNfMJyrN92C1kxpfHX2AptFpn8A-1785241875.1743767-1.0.1.1-TrJ9RIKM0czNhwVBLYzIejgJdhe_7Jvnic.f.Sv5U_d4W7HwBcgLGkCcWkA999QEiF8LZcsyWMJmr3koiFfAMgl0u1CzT2JqweA2KLFzvkz2cRHlcaqkWACOq3HGGxaj; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","cf-ray":"a223e657ca9f7db6-LAX","alt-svc":"h3=\":443\"; ma=86400","access-control-allow-origin":"*","content-length":"2081","content-security-policy":"default-src 'none'; script-src 'none'; style-src 'none'; img-src 'none'; font-src 'none'; connect-src 'none'; frame-src 'none'; object-src 'none'; frame-ancestors 'none'; sandbox; form-action 'none';","accept-ranges":"bytes","content-type":"text/typescript","vary":"Origin","access-control-expose-headers":"*","date":"Tue, 28 Jul 2026 12:31:15 GMT","server":"cloudflare","x-jsr-backend":"modules","x-robots-tag":"noindex","x-content-type-options":"nosniff","etag":"\"fb2c2c961dab13ca46e1ae0d9c245d03\"","age":"1336394","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=4z1d8jMfQeNKwXi1H8jElgQnX2OaZPb8%2FQ4lhv5wNpJ6h56N1L4g1AWPIwY7%2FTTL5rQkiDq%2B%2FqKSewZOSHBSwv2Zw1m8eiXANqtYK2j4qbUJ7ZVV4LiImeQ%3D\"}]}","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","cf-cache-status":"HIT"},"url":"https://jsr.io/@std/semver/0.224.3/less_than_range.ts","time":1785241875}