import npath from "path";
import { findElements, getTagName, getAttribute, findNodes, hasAttribute } from "@web/parse5-utils";
import adapter from "parse5/lib/tree-adapters/default.js";
const hashedLinkRels = ["stylesheet", "preload"];
const linkRels = [...hashedLinkRels, "icon", "manifest", "apple-touch-icon", "mask-icon"];
const windowsPathRE = /^[A-Z]:\//;
function getSrcSetUrls(srcset) {
  if (!srcset) {
    return [];
  }
  const srcsetParts = srcset.includes(",") ? srcset.split(",") : [srcset];
  const urls = srcsetParts.map((url) => url.trim()).map((url) => url.includes(" ") ? url.split(" ")[0] : url);
  return urls;
}
function extractFirstUrlOfSrcSet(node) {
  const srcset = getAttribute(node, "srcset");
  if (!srcset) {
    return "";
  }
  const urls = getSrcSetUrls(srcset);
  return urls[0];
}
function isAsset(node) {
  var _a, _b, _c, _d, _e, _f;
  let path = "";
  switch (getTagName(node)) {
    case "img":
      path = (_a = getAttribute(node, "src")) != null ? _a : "";
      break;
    case "source":
      path = (_b = extractFirstUrlOfSrcSet(node)) != null ? _b : "";
      break;
    case "link":
      if (linkRels.includes((_c = getAttribute(node, "rel")) != null ? _c : "")) {
        path = (_d = getAttribute(node, "href")) != null ? _d : "";
      }
      break;
    case "meta":
      if (getAttribute(node, "property") === "og:image" && getAttribute(node, "content")) {
        path = (_e = getAttribute(node, "content")) != null ? _e : "";
      }
      break;
    case "script":
      if (getAttribute(node, "type") !== "module" && getAttribute(node, "src")) {
        path = (_f = getAttribute(node, "src")) != null ? _f : "";
      }
      break;
    default:
      return false;
  }
  if (!path) {
    return false;
  }
  if (windowsPathRE.test(path)) {
    return true;
  }
  try {
    new URL(path);
    return false;
  } catch (e) {
    return true;
  }
}
function isInlineScript(node) {
  switch (getTagName(node)) {
    case "script":
      if (getAttribute(node, "type") === "module" && !getAttribute(node, "src")) {
        return true;
      }
      return false;
    default:
      return false;
  }
}
function isExternalScript(node) {
  switch (getTagName(node)) {
    case "script":
      if (hasAttribute(node, "src")) {
        return true;
      }
      return false;
    default:
      return false;
  }
}
function isInlineStyle(node) {
  return getTagName(node) === "style";
}
function isStylesheetLink(node) {
  return getTagName(node) === "link" && getAttribute(node, "rel") === "stylesheet";
}
function isHashedAsset(node) {
  switch (getTagName(node)) {
    case "img":
      return true;
    case "source":
      return true;
    case "script":
      return true;
    case "link":
      return hashedLinkRels.includes(getAttribute(node, "rel"));
    case "meta":
      return true;
    default:
      return false;
  }
}
function resolveAssetFilePath(browserPath, htmlDir, projectRootDir, absolutePathPrefix) {
  const _browserPath = absolutePathPrefix && browserPath[0] === "/" ? "/" + npath.posix.relative(absolutePathPrefix, browserPath) : browserPath;
  return npath.join(_browserPath.startsWith("/") ? projectRootDir : htmlDir, _browserPath.split("/").join(npath.sep));
}
function getSourceAttribute(node) {
  switch (getTagName(node)) {
    case "img": {
      return "src";
    }
    case "source": {
      return "srcset";
    }
    case "link": {
      return "href";
    }
    case "script": {
      return "src";
    }
    case "meta": {
      return "content";
    }
    default:
      throw new Error(`Unknown node with tagname ${getTagName(node)}`);
  }
}
function getSourcePaths(node) {
  var _a;
  const key = getSourceAttribute(node);
  let location = { start: 0, end: 0 };
  const src = getAttribute(node, key);
  if (node.sourceCodeLocation) {
    let loc = (_a = node.sourceCodeLocation.attrs) == null ? void 0 : _a[key];
    if (loc) {
      location.start = loc.startOffset;
      location.end = loc.endOffset;
    }
  }
  if (typeof key !== "string" || src === "") {
    throw new Error(`Missing attribute ${key} in element ${node.nodeName}`);
  }
  let paths = [];
  if (src && key === "srcset") {
    paths = getSrcSetUrls(src).map((path) => ({
      path,
      location
    }));
  } else if (src) {
    paths.push({
      path: src,
      location
    });
  }
  return paths;
}
function getTextContent(node) {
  if (adapter.isCommentNode(node)) {
    return node.data || "";
  }
  if (adapter.isTextNode(node)) {
    return node.value || "";
  }
  const subtree = findNodes(node, (n) => adapter.isTextNode(n));
  return subtree.map(getTextContent).join("");
}
function getAttributes(node) {
  return Object.fromEntries(node.attrs.map((attr) => [attr.name, attr.value]));
}
function findAssets(document) {
  return findElements(document, isAsset);
}
function findInlineScripts(document) {
  return findElements(document, isInlineScript);
}
function findExternalScripts(document) {
  return findElements(document, isExternalScript);
}
function findInlineStyles(document) {
  return findElements(document, isInlineStyle);
}
function findStyleLinks(document) {
  return findElements(document, isStylesheetLink);
}
export {
  findAssets,
  findExternalScripts,
  findInlineScripts,
  findInlineStyles,
  findStyleLinks,
  getAttributes,
  getSourceAttribute,
  getSourcePaths,
  getTextContent,
  isHashedAsset,
  isStylesheetLink,
  resolveAssetFilePath
};
//# sourceMappingURL=data:application/json;base64, 
