import fastify, { FastifyInstance, FastifyPluginCallback } from 'fastify'
import { expect } from 'tstyche'
import * as fastifyAutoloadStar from '.'
import fastifyAutoloadDefault, { AutoloadPluginOptions, fastifyAutoload as fastifyAutoloadNamed } from '.'
import * as fastifyAutoloadCjsImport from '.'

const fastifyAutoloadCjs = require('..')

const app: FastifyInstance = fastify()
app.register(fastifyAutoloadNamed, { dir: 'test' })
app.register(fastifyAutoloadDefault, { dir: 'test' })
app.register(fastifyAutoloadCjs, { dir: 'test' })
app.register(fastifyAutoloadCjsImport.default, { dir: 'test' })
app.register(fastifyAutoloadCjsImport.fastifyAutoload, { dir: 'test' })
app.register(fastifyAutoloadStar.default, { dir: 'test' })
app.register(fastifyAutoloadStar.fastifyAutoload, { dir: 'test' })

expect(fastifyAutoloadNamed).type.toBe<FastifyPluginCallback<AutoloadPluginOptions>>()
expect(fastifyAutoloadDefault).type.toBe<FastifyPluginCallback<AutoloadPluginOptions>>()
expect(fastifyAutoloadCjsImport.default).type.toBe<FastifyPluginCallback<AutoloadPluginOptions>>()
expect(fastifyAutoloadCjsImport.fastifyAutoload).type.toBe<FastifyPluginCallback<AutoloadPluginOptions>>()
expect(fastifyAutoloadStar.default).type.toBe<FastifyPluginCallback<AutoloadPluginOptions>>()
expect(fastifyAutoloadStar.fastifyAutoload).type.toBe<FastifyPluginCallback<AutoloadPluginOptions>>()
expect(fastifyAutoloadCjs).type.toBe<any>()

const opt1: AutoloadPluginOptions = {
  dir: 'test'
}
const opt2: AutoloadPluginOptions = {
  dir: 'test',
  ignorePattern: /skip/
}
const opt3: AutoloadPluginOptions = {
  dir: 'test',
  scriptPattern: /js/,
  indexPattern: /index/,
}
const opt4: AutoloadPluginOptions = {
  dir: 'test',
  options: {
    prefix: 'test'
  }
}
const opt5: AutoloadPluginOptions = {
  dir: 'test',
  maxDepth: 1,
}
const opt6: AutoloadPluginOptions = {
  dir: 'test',
  routeParams: true,
}
const opt7: AutoloadPluginOptions = {
  dir: 'test',
  forceESM: true,
  autoHooks: true,
  autoHooksPattern: /^[_.]?auto_?hooks(?:\.ts|\.js|\.cjs|\.mjs)$/i,
  cascadeHooks: true,
  overwriteHooks: true,
}
const opt8: AutoloadPluginOptions = {
  dir: 'test',
  encapsulate: false,
}
const opt9: AutoloadPluginOptions = {
  dir: 'test',
  ignoreFilter: /test/,
  matchFilter: /handler/
}
const opt10: AutoloadPluginOptions = {
  dir: 'test',
  ignoreFilter: 'test',
  matchFilter: 'handler'
}
const opt11: AutoloadPluginOptions = {
  dir: 'test',
  ignoreFilter: (path) => path.endsWith('.spec.ts'),
  matchFilter: (path) => path.split('/').at(-2) === 'handlers'
}
app.register(fastifyAutoloadDefault, opt1)
app.register(fastifyAutoloadDefault, opt2)
app.register(fastifyAutoloadDefault, opt3)
app.register(fastifyAutoloadDefault, opt4)
app.register(fastifyAutoloadDefault, opt5)
app.register(fastifyAutoloadDefault, opt6)
app.register(fastifyAutoloadDefault, opt7)
app.register(fastifyAutoloadDefault, opt8)
app.register(fastifyAutoloadDefault, opt9)
app.register(fastifyAutoloadDefault, opt10)
app.register(fastifyAutoloadDefault, opt11)

expect(app.register).type.not.toBeCallableWith(fastifyAutoloadDefault, {
  dir: 'test',
  invalidOption: true
})
