import * as path from "path";
import esbuild from "esbuild";
import { STYLE_EXTENSIONS } from "../core/ssr/css.js";
const PLUGIN_NAME = "@astrojs/rollup-plugin-build-css";
const ASTRO_STYLE_PREFIX = "@astro-inline-style";
const ASTRO_PAGE_STYLE_PREFIX = "@astro-page-all-styles";
const cssRe = new RegExp(`\\.(${Array.from(STYLE_EXTENSIONS).map((s) => s.slice(1)).join("|")})($|\\?)`);
const isCSSRequest = (request) => cssRe.test(request);
function getAstroPageStyleId(pathname) {
  let styleId = ASTRO_PAGE_STYLE_PREFIX + pathname;
  if (styleId.endsWith("/")) {
    styleId += "index";
  }
  styleId += ".js";
  return styleId;
}
function getAstroStyleId(pathname) {
  let styleId = ASTRO_STYLE_PREFIX + pathname;
  if (styleId.endsWith("/")) {
    styleId += "index";
  }
  return styleId;
}
function getAstroStylePathFromId(id) {
  return id.substr(ASTRO_STYLE_PREFIX.length + 1);
}
function isStyleVirtualModule(id) {
  return id.startsWith(ASTRO_STYLE_PREFIX);
}
function isPageStyleVirtualModule(id) {
  return id.startsWith(ASTRO_PAGE_STYLE_PREFIX);
}
function rollupPluginAstroBuildCSS(options) {
  const { internals } = options;
  const styleSourceMap = new Map();
  return {
    name: PLUGIN_NAME,
    configResolved(resolvedConfig) {
      const plugins = resolvedConfig.plugins;
      const viteCSSPostIndex = resolvedConfig.plugins.findIndex((p) => p.name === "vite:css-post");
      if (viteCSSPostIndex !== -1) {
        const viteCSSPost = plugins[viteCSSPostIndex];
        delete viteCSSPost.renderChunk;
        delete viteCSSPost.generateBundle;
        const ourIndex = plugins.findIndex((p) => p.name === PLUGIN_NAME);
        const ourPlugin = plugins[ourIndex];
        plugins.splice(ourIndex, 1);
        plugins.splice(viteCSSPostIndex - 1, 0, ourPlugin);
      }
    },
    async resolveId(id) {
      if (isPageStyleVirtualModule(id)) {
        return id;
      }
      if (isStyleVirtualModule(id)) {
        return id;
      }
      return void 0;
    },
    async load(id) {
      if (isPageStyleVirtualModule(id)) {
        return internals.astroPageStyleMap.get(id) || null;
      }
      if (isStyleVirtualModule(id)) {
        return internals.astroStyleMap.get(id) || null;
      }
      return null;
    },
    async transform(value, id) {
      if (isStyleVirtualModule(id)) {
        styleSourceMap.set(id, value);
      }
      if (isCSSRequest(id)) {
        styleSourceMap.set(id, value);
      }
      return null;
    },
    async renderChunk(_code, chunk) {
      let chunkCSS = "";
      let isPureCSS = true;
      for (const [id] of Object.entries(chunk.modules)) {
        if (!isCSSRequest(id) && !isPageStyleVirtualModule(id)) {
          isPureCSS = false;
        }
        if (styleSourceMap.has(id)) {
          chunkCSS += styleSourceMap.get(id);
        }
      }
      if (!chunkCSS)
        return null;
      if (isPureCSS) {
        internals.pureCSSChunks.add(chunk);
      }
      const { code: minifiedCSS } = await esbuild.transform(chunkCSS, {
        loader: "css",
        minify: true
      });
      const referenceId = this.emitFile({
        name: chunk.name + ".css",
        type: "asset",
        source: minifiedCSS
      });
      internals.chunkToReferenceIdMap.set(chunk.fileName, referenceId);
      if (chunk.type === "chunk") {
        const fileName = this.getFileName(referenceId);
        if (chunk.facadeModuleId) {
          const facadeId = chunk.facadeModuleId;
          if (!internals.facadeIdToAssetsMap.has(facadeId)) {
            internals.facadeIdToAssetsMap.set(facadeId, []);
          }
          internals.facadeIdToAssetsMap.get(facadeId).push(fileName);
        }
      }
      return null;
    },
    generateBundle(opts, bundle) {
      const hasPureCSSChunks = internals.pureCSSChunks.size;
      const pureChunkFilenames = new Set([...internals.pureCSSChunks].map((chunk) => chunk.fileName));
      const emptyChunkFiles = [...pureChunkFilenames].map((file) => path.basename(file)).join("|").replace(/\./g, "\\.");
      const emptyChunkRE = new RegExp(opts.format === "es" ? `\\bimport\\s*"[^"]*(?:${emptyChunkFiles})";
?` : `\\brequire\\(\\s*"[^"]*(?:${emptyChunkFiles})"\\);
?`, "g");
      for (const [chunkId, chunk] of Object.entries(bundle)) {
        if (chunk.type === "chunk") {
          if (chunk.facadeModuleId) {
            if (!internals.facadeIdToAssetsMap.has(chunk.facadeModuleId)) {
              internals.facadeIdToAssetsMap.set(chunk.facadeModuleId, []);
            }
            const assets = internals.facadeIdToAssetsMap.get(chunk.facadeModuleId);
            const assetSet = new Set(assets);
            for (const imp of chunk.imports) {
              if (internals.chunkToReferenceIdMap.has(imp) && !pureChunkFilenames.has(imp)) {
                const referenceId = internals.chunkToReferenceIdMap.get(imp);
                const fileName = this.getFileName(referenceId);
                if (!assetSet.has(fileName)) {
                  assetSet.add(fileName);
                  assets.push(fileName);
                }
              }
            }
          }
          if (hasPureCSSChunks) {
            if (internals.pureCSSChunks.has(chunk)) {
              delete bundle[chunkId];
            } else {
              chunk.code = chunk.code.replace(emptyChunkRE, (m) => `/* empty css ${"".padEnd(m.length - 15)}*/`);
            }
          }
        }
      }
    }
  };
}
export {
  getAstroPageStyleId,
  getAstroStyleId,
  getAstroStylePathFromId,
  rollupPluginAstroBuildCSS
};
//# sourceMappingURL=data:application/json;base64, 
