import type { Vite } from 'vitest/node'
import remapping from '@jridgewell/remapping'
import MagicString from 'magic-string'
import { defineConfig } from 'vitest/config'
import { cwdPlugin } from './cwdPlugin.js'

export default defineConfig({
  envPrefix: ['VITE_', 'CUSTOM_', 'ROOT_'],
  plugins: [cwdPlugin('ROOT')],
  test: {
    coverage: {
      enabled: true,
      provider: 'istanbul',
    },
    reporters: ['default', 'json'],
    outputFile: './results.json',
    globalSetup: './globalTest.ts',
    env: {
      CONFIG_VAR: 'root',
      CONFIG_OVERRIDE: 'root',
    },
    provide: {
      globalConfigValue: true,
    },
    projects: [
      'space_2',
      './space_*/vitest.config.ts',
      './space_1/*.config.ts',
      async () => ({
        test: {
          name: 'happy-dom',
          root: './space_shared',
          environment: 'happy-dom',
          setupFiles: ['./setup.jsdom.ts'],
          provide: {
            providedConfigValue: 'actual config value',
          },
        },
      }),
      Promise.resolve({
        test: {
          name: 'node',
          root: './space_shared',
          environment: 'node',
          setupFiles: ['./setup.node.ts'],
        },
      }),

      // Projects testing pool and poolOptions
      {
        test: {
          name: 'Threads pool',
          include: [
            './space-pools/threads.test.ts',
            './space-pools/isolate.test.ts',
          ],
          pool: 'threads',
        },
      },
      {
        test: {
          name: 'Non-parallel thread pool',
          include: [
            './space-pools/threads.test.ts',
          ],
          pool: 'threads',
          fileParallelism: false,
        },
      },
      {
        test: {
          name: 'Non-isolated thread pool',
          include: [
            './space-pools/threads.test.ts',
            './space-pools/no-isolate.test.ts',
          ],
          pool: 'threads',
          isolate: false,
        },
      },
      {
        test: {
          name: 'Forks pool',
          include: [
            './space-pools/forks.test.ts',
            './space-pools/isolate.test.ts',
          ],
          pool: 'forks',
        },
      },
      {
        test: {
          name: 'Non-parallel fork pool',
          include: [
            './space-pools/forks.test.ts',
          ],
          pool: 'forks',
          fileParallelism: false,
        },
      },
      {
        test: {
          name: 'Non-isolated fork pool',
          include: [
            './space-pools/forks.test.ts',
            './space-pools/no-isolate.test.ts',
          ],
          pool: 'forks',
          isolate: false,
        },
      },

      // These two projects run on same environment but still transform
      // a single file differently due to Vite plugins
      {
        plugins: [customPlugin(0)],
        test: {
          name: 'Project with custom plugin #1',
          environment: 'node',
          include: ['./space-multi-transform/test/project-1.test.ts'],
        },
      },
      {
        plugins: [customPlugin(15)],
        test: {
          name: 'Project with custom plugin #2',
          environment: 'node',
          include: ['./space-multi-transform/test/project-2.test.ts'],
        },
      },
    ],
  },
})

function customPlugin(offset: number): Vite.Plugin {
  return {
    name: 'vitest-custom-multi-transform',
    enforce: 'pre',
    transform(code, id) {
      if (id.includes('space-multi-transform/src/multi-transform.ts')) {
        const padding = '\n*****'.repeat(offset)

        const transformed = new MagicString(code)
        transformed.replace('\'default-padding\'', `\`${padding}\``)

        const map = remapping(
          [transformed.generateMap({ hires: true }), this.getCombinedSourcemap() as any],
          () => null,
        ) as any

        return { code: transformed.toString(), map }
      }
    },
  }
}
