"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const extpath = require("./extpath.js");
const network = require("./network.js");
const path = require("./path.js");
const platform = require("./platform.js");
const strings = require("./strings.js");
const uri = require("./uri.js");
function originalFSPath(uri$1) {
  return uri.uriToFsPath(uri$1, true);
}
class ExtUri {
  constructor(_ignorePathCasing) {
    this._ignorePathCasing = _ignorePathCasing;
  }
  compare(uri1, uri2, ignoreFragment = false) {
    if (uri1 === uri2) {
      return 0;
    }
    return strings.compare(this.getComparisonKey(uri1, ignoreFragment), this.getComparisonKey(uri2, ignoreFragment));
  }
  isEqual(uri1, uri2, ignoreFragment = false) {
    if (uri1 === uri2) {
      return true;
    }
    if (!uri1 || !uri2) {
      return false;
    }
    return this.getComparisonKey(uri1, ignoreFragment) === this.getComparisonKey(uri2, ignoreFragment);
  }
  getComparisonKey(uri2, ignoreFragment = false) {
    return uri2.with({
      path: this._ignorePathCasing(uri2) ? uri2.path.toLowerCase() : void 0,
      fragment: ignoreFragment ? null : void 0
    }).toString();
  }
  isEqualOrParent(base, parentCandidate, ignoreFragment = false) {
    if (base.scheme === parentCandidate.scheme) {
      if (base.scheme === network.Schemas.file) {
        return extpath.isEqualOrParent(originalFSPath(base), originalFSPath(parentCandidate), this._ignorePathCasing(base)) && base.query === parentCandidate.query && (ignoreFragment || base.fragment === parentCandidate.fragment);
      }
      if (isEqualAuthority(base.authority, parentCandidate.authority)) {
        return extpath.isEqualOrParent(base.path, parentCandidate.path, this._ignorePathCasing(base), "/") && base.query === parentCandidate.query && (ignoreFragment || base.fragment === parentCandidate.fragment);
      }
    }
    return false;
  }
  // --- path math
  joinPath(resource, ...pathFragment) {
    return uri.URI.joinPath(resource, ...pathFragment);
  }
  basenameOrAuthority(resource) {
    return basename(resource) || resource.authority;
  }
  basename(resource) {
    return path.posix.basename(resource.path);
  }
  extname(resource) {
    return path.posix.extname(resource.path);
  }
  dirname(resource) {
    if (resource.path.length === 0) {
      return resource;
    }
    let dirname2;
    if (resource.scheme === network.Schemas.file) {
      dirname2 = uri.URI.file(path.dirname(originalFSPath(resource))).path;
    } else {
      dirname2 = path.posix.dirname(resource.path);
      if (resource.authority && dirname2.length && dirname2.charCodeAt(0) !== 47) {
        console.error(`dirname("${resource.toString})) resulted in a relative path`);
        dirname2 = "/";
      }
    }
    return resource.with({
      path: dirname2
    });
  }
  normalizePath(resource) {
    if (!resource.path.length) {
      return resource;
    }
    let normalizedPath;
    if (resource.scheme === network.Schemas.file) {
      normalizedPath = uri.URI.file(path.normalize(originalFSPath(resource))).path;
    } else {
      normalizedPath = path.posix.normalize(resource.path);
    }
    return resource.with({
      path: normalizedPath
    });
  }
  relativePath(from, to) {
    if (from.scheme !== to.scheme || !isEqualAuthority(from.authority, to.authority)) {
      return void 0;
    }
    if (from.scheme === network.Schemas.file) {
      const relativePath = path.relative(originalFSPath(from), originalFSPath(to));
      return platform.isWindows ? extpath.toSlashes(relativePath) : relativePath;
    }
    let fromPath = from.path || "/", toPath = to.path || "/";
    if (this._ignorePathCasing(from)) {
      let i = 0;
      for (const len = Math.min(fromPath.length, toPath.length); i < len; i++) {
        if (fromPath.charCodeAt(i) !== toPath.charCodeAt(i)) {
          if (fromPath.charAt(i).toLowerCase() !== toPath.charAt(i).toLowerCase()) {
            break;
          }
        }
      }
      fromPath = toPath.substr(0, i) + fromPath.substr(i);
    }
    return path.posix.relative(fromPath, toPath);
  }
  resolvePath(base, path$1) {
    if (base.scheme === network.Schemas.file) {
      const newURI = uri.URI.file(path.resolve(originalFSPath(base), path$1));
      return base.with({
        authority: newURI.authority,
        path: newURI.path
      });
    }
    path$1 = extpath.toPosixPath(path$1);
    return base.with({
      path: path.posix.resolve(base.path, path$1)
    });
  }
  // --- misc
  isAbsolutePath(resource) {
    return !!resource.path && resource.path[0] === "/";
  }
  isEqualAuthority(a1, a2) {
    return a1 === a2 || a1 !== void 0 && a2 !== void 0 && strings.equalsIgnoreCase(a1, a2);
  }
  hasTrailingPathSeparator(resource, sep = path.sep) {
    if (resource.scheme === network.Schemas.file) {
      const fsp = originalFSPath(resource);
      return fsp.length > extpath.getRoot(fsp).length && fsp[fsp.length - 1] === sep;
    } else {
      const p = resource.path;
      return p.length > 1 && p.charCodeAt(p.length - 1) === 47 && !/^[a-zA-Z]:(\/$|\\$)/.test(resource.fsPath);
    }
  }
  removeTrailingPathSeparator(resource, sep = path.sep) {
    if (hasTrailingPathSeparator(resource, sep)) {
      return resource.with({ path: resource.path.substr(0, resource.path.length - 1) });
    }
    return resource;
  }
  addTrailingPathSeparator(resource, sep = path.sep) {
    let isRootSep = false;
    if (resource.scheme === network.Schemas.file) {
      const fsp = originalFSPath(resource);
      isRootSep = fsp !== void 0 && fsp.length === extpath.getRoot(fsp).length && fsp[fsp.length - 1] === sep;
    } else {
      sep = "/";
      const p = resource.path;
      isRootSep = p.length === 1 && p.charCodeAt(p.length - 1) === 47;
    }
    if (!isRootSep && !hasTrailingPathSeparator(resource, sep)) {
      return resource.with({ path: resource.path + "/" });
    }
    return resource;
  }
}
const extUri = new ExtUri(() => false);
const isEqual = extUri.isEqual.bind(extUri);
extUri.isEqualOrParent.bind(extUri);
extUri.getComparisonKey.bind(extUri);
const basenameOrAuthority = extUri.basenameOrAuthority.bind(extUri);
const basename = extUri.basename.bind(extUri);
const extname = extUri.extname.bind(extUri);
const dirname = extUri.dirname.bind(extUri);
const joinPath = extUri.joinPath.bind(extUri);
const normalizePath = extUri.normalizePath.bind(extUri);
extUri.relativePath.bind(extUri);
const resolvePath = extUri.resolvePath.bind(extUri);
extUri.isAbsolutePath.bind(extUri);
const isEqualAuthority = extUri.isEqualAuthority.bind(extUri);
const hasTrailingPathSeparator = extUri.hasTrailingPathSeparator.bind(extUri);
extUri.removeTrailingPathSeparator.bind(extUri);
extUri.addTrailingPathSeparator.bind(extUri);
exports.DataUri = void 0;
(function(DataUri) {
  DataUri.META_DATA_LABEL = "label";
  DataUri.META_DATA_DESCRIPTION = "description";
  DataUri.META_DATA_SIZE = "size";
  DataUri.META_DATA_MIME = "mime";
  function parseMetaData(dataUri) {
    const metadata = /* @__PURE__ */ new Map();
    const meta = dataUri.path.substring(dataUri.path.indexOf(";") + 1, dataUri.path.lastIndexOf(";"));
    meta.split(";").forEach((property) => {
      const [key, value] = property.split(":");
      if (key && value) {
        metadata.set(key, value);
      }
    });
    const mime = dataUri.path.substring(0, dataUri.path.indexOf(";"));
    if (mime) {
      metadata.set(DataUri.META_DATA_MIME, mime);
    }
    return metadata;
  }
  DataUri.parseMetaData = parseMetaData;
})(exports.DataUri || (exports.DataUri = {}));
exports.ExtUri = ExtUri;
exports.basename = basename;
exports.basenameOrAuthority = basenameOrAuthority;
exports.dirname = dirname;
exports.extUri = extUri;
exports.extname = extname;
exports.hasTrailingPathSeparator = hasTrailingPathSeparator;
exports.isEqual = isEqual;
exports.isEqualAuthority = isEqualAuthority;
exports.joinPath = joinPath;
exports.normalizePath = normalizePath;
exports.originalFSPath = originalFSPath;
exports.resolvePath = resolvePath;
