/// Code taken from https://github.com/rollup/plugins/blob/master/packages/yaml/src/index.js

import {
  createFilter,
  makeLegalIdentifier,
  type FilterPattern,
} from "@rollup/pluginutils"
import YAML, { type LoadOptions } from "js-yaml"
import toSource from "tosource"
import type { PluginOption } from "vite"

interface Options extends LoadOptions {
  documentMode?: "multi" | "single"
  exclude?: FilterPattern | undefined
  include?: FilterPattern | undefined
  transform?: ((data: unknown, id: string) => unknown) | null
}
const defaults: Options = {
  documentMode: "single",
  transform: null,
}
const ext = /\.ya?ml$/

export default function yaml(opts: Options = {}): PluginOption {
  const options = Object.assign({}, defaults, opts)
  const { documentMode } = options
  const filter = createFilter(options.include, options.exclude)
  let loadMethod: (str: string, opts?: LoadOptions) => unknown

  if (documentMode === "single") {
    loadMethod = YAML.load
  } else if (documentMode === "multi") {
    loadMethod = YAML.loadAll as (str: string, opts?: LoadOptions) => unknown
  } else {
    this.error(
      `plugin-yaml → documentMode: '${documentMode}' is not a valid value. Please choose 'single' or 'multi'`,
    )
  }

  return {
    name: "yaml",

    transform(content: string, id: string) {
      if (!ext.test(id)) return null
      if (!filter(id)) return null

      // The pach is here: it adds `options` argument.
      let data = loadMethod(content, options)

      if (typeof options.transform === "function") {
        const result = options.transform(data, id)
        if (result !== undefined) {
          data = result
        }
      }

      const keys = Object.keys(data).filter(
        (key) => key === makeLegalIdentifier(key),
      )
      const code = `var data = ${toSource(data)};\n\n`
      const exports = ["export default data;"]
        .concat(keys.map((key) => `export var ${key} = data.${key};`))
        .join("\n")

      return {
        code: code + exports,
        map: { mappings: "" },
      }
    },
  }
}