// 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 greater than the range.
 *
 * @example Usage
 * ```ts
 * import { parse, parseRange, greaterThanRange } from "@std/semver";
 * import { assert, assertFalse } from "@std/assert";
 *
 * const v0 = parse("1.2.3");
 * const v1 = parse("1.2.4");
 * const range = parseRange(">=1.2.3 <1.2.4");
 * assertFalse(greaterThanRange(v0, range));
 * assert(greaterThanRange(v1, range));
 * ```
 *
 * @param semver The version to check.
 * @param range The range to check against.
 * @returns `true` if the semver is greater than the range, `false` otherwise.
 */
export function greaterThanRange(semver: SemVer, range: Range): boolean {
  return range.every((comparatorSet) =>
    greaterThanComparatorSet(semver, comparatorSet)
  );
}

function greaterThanComparatorSet(
  semver: SemVer,
  comparatorSet: Comparator[],
): boolean {
  // 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 greater than the range.
  if (testComparatorSet(semver, comparatorSet)) return false;
  // If the semver is less than any of the comparator set, then it's not greater than the range.
  if (
    comparatorSet.some((comparator) => lessThanComparator(semver, comparator))
  ) return false;
  return true;
}

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

// denoCacheMetadata={"headers":{"x-jsr-backend":"modules","x-robots-tag":"noindex","set-cookie":"__cf_bm=pG0LD65Yhs1uiF4CNr73GSmbNsLTOqzP7UbFQLWx11g-1785241875.173212-1.0.1.1-mKC33DaZ_hFQMNZPszA2kdzY530WMGN1CQbfEzRyVKWKneQxrh3D7y9FV68zVJZEuwKE3GIuIzOg59h.gy8oe9YIWivJh74xtzy7ibuDL3F2wZeWEb4BARp4xkPc_oDo; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","date":"Tue, 28 Jul 2026 12:31:15 GMT","content-type":"text/typescript","cross-origin-resource-policy":"cross-origin","cf-cache-status":"HIT","content-length":"2100","etag":"\"a9b484757612776df23fd31e5609fb3b\"","age":"36703","server":"cloudflare","cache-control":"public, max-age=31536000, immutable","access-control-expose-headers":"*","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=lyznXfBUPiKZnPe5AilFMp2UdSGJ8KIJQNF1G8vWGknDBQEMRSYp%2BgVDHwYLtL%2F4RMXtap6zdLdC1%2FuJ8jALvJn9IqoxSRjF%2BieSCoVvKL6XSS4NYbiacA8%3D\"}]}","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","accept-ranges":"bytes","access-control-allow-origin":"*","vary":"Origin","alt-svc":"h3=\":443\"; ma=86400","cf-ray":"a223e657ca9b7db6-LAX","x-content-type-options":"nosniff","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';"},"url":"https://jsr.io/@std/semver/0.224.3/greater_than_range.ts","time":1785241875}