import ScriptLoaderClient from './client'

import defaultTransformer from './transformers/_default'
import glslTransformer from './transformers/glsl'
import javascriptTransformer from './transformers/javascript'
import webassemblyTransformer from './transformers/webassembly'

import type { ResourceFileParam, StringParam, TransformResult } from './types'

interface Props {
  [propName: string]: string | undefined
}

const transformers = [
  javascriptTransformer,
  webassemblyTransformer,
  glslTransformer,
  defaultTransformer
]

export default async function ScriptServer(props: Props) {
  let transformedProps: {[name: string] : TransformResult} = {}
  propLoop: for (const propName in props) {
    const propValue = props[propName]
    if (typeof propValue !== 'string')
      continue

    const extension = propValue.split('.').at(-1)

    for (const transformer of transformers) {
      if (transformer.extension === '*' || transformer.extension === extension) {
        transformedProps[propName] = await transformer.transform(propValue)
        continue propLoop
      }
    }

    throw new Error(`Cannot transform prop ${propName} with value ${propValue}`)
  }

  if (!transformedProps.src) {
    throw new Error("No script source specified")
  }

  if (transformedProps.src.type !== 'script') {
    throw new Error("Script source is not of type script")
  }

  if (transformedProps.wasm !== undefined && transformedProps.wasm.type !== 'wasm') {
    throw new Error(`Wasm prop cannot be of type ${transformedProps.wasm.type}`)
  }

  const {src, wasm, ...rest} = transformedProps


  return (
    <ScriptLoaderClient
      src={src}
      wasm={wasm}
      rest={rest as {[name: string]: StringParam | ResourceFileParam}}
    />
  )
}
