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

import { assertPath } from "../_common/assert_path.ts";
import { isPathSeparator } from "./_util.ts";
import { normalize } from "./normalize.ts";

/**
 * Join all given a sequence of `paths`,then normalizes the resulting path.
 *
 * @example Usage
 * ```ts
 * import { join } from "@std/path/windows/join";
 * import { assertEquals } from "@std/assert/assert-equals";
 *
 * const joined = join("C:\\foo", "bar", "baz\\..");
 * assertEquals(joined, "C:\\foo\\bar");
 * ```
 *
 * @param paths The paths to join.
 * @returns The joined path.
 */
export function join(...paths: string[]): string {
  paths.forEach((path) => assertPath(path));
  paths = paths.filter((path) => path.length > 0);
  if (paths.length === 0) return ".";

  // Make sure that the joined path doesn't start with two slashes, because
  // normalize() will mistake it for an UNC path then.
  //
  // This step is skipped when it is very clear that the user actually
  // intended to point at an UNC path. This is assumed when the first
  // non-empty string arguments starts with exactly two slashes followed by
  // at least one more non-slash character.
  //
  // Note that for normalize() to treat a path as an UNC path it needs to
  // have at least 2 components, so we don't filter for that here.
  // This means that the user can use join to construct UNC paths from
  // a server name and a share name; for example:
  //   path.join('//server', 'share') -> '\\\\server\\share\\'
  let needsReplace = true;
  let slashCount = 0;
  const firstPart = paths[0]!;
  if (isPathSeparator(firstPart.charCodeAt(0))) {
    ++slashCount;
    const firstLen = firstPart.length;
    if (firstLen > 1) {
      if (isPathSeparator(firstPart.charCodeAt(1))) {
        ++slashCount;
        if (firstLen > 2) {
          if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount;
          else {
            // We matched a UNC path in the first part
            needsReplace = false;
          }
        }
      }
    }
  }
  let joined = paths.join("\\");
  if (needsReplace) {
    // Find any more consecutive slashes we need to replace
    for (; slashCount < joined.length; ++slashCount) {
      if (!isPathSeparator(joined.charCodeAt(slashCount))) break;
    }

    // Replace the slashes if needed
    if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`;
  }

  return normalize(joined);
}

// denoCacheMetadata={"headers":{"etag":"\"574728fa55318b173b7819b55bf5b02f\"","content-type":"text/typescript","access-control-allow-origin":"*","vary":"Origin","date":"Tue, 28 Jul 2026 12:31:15 GMT","x-jsr-backend":"modules","content-length":"2483","access-control-expose-headers":"*","set-cookie":"__cf_bm=fTYsQMdxTiOXWIai.PoqavVnhtl62KF5OqUcwR0cqCc-1785241875.3442585-1.0.1.1-_ZWGlpnfKhkp7S.uIcQTioXiJ6rhReTr_a7vcoMCPF3jRVOTsKMw7PZkNFCQgwYBScdiQQwVyOAoRPfzQVc2iHl3j0G2acTpqYsMTWUPU5hEAfxOz_bpSg.aaFvfVSoU; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=VIRH4pUGCL2B%2B20tVM79yq1MWovh122e1884PvrHaPTb2kz7aEAkCT9I6AVii69udCwcoozfmJR1wYqYiIMIHq91O1rdl0D%2FJAW6lMc56t%2BI9ww%2FV9401hE%3D\"}]}","server":"cloudflare","cross-origin-resource-policy":"cross-origin","cf-cache-status":"HIT","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","alt-svc":"h3=\":443\"; ma=86400","x-content-type-options":"nosniff","accept-ranges":"bytes","age":"126790","cache-control":"public, max-age=31536000, immutable","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';","cf-ray":"a223e658cdb67db6-LAX","x-robots-tag":"noindex"},"url":"https://jsr.io/@std/path/1.0.0-rc.2/windows/join.ts","time":1785241875}