'use strict'

const http = require('node:http')
const AjvStandaloneCompiler = require('@fastify/ajv-compiler/standalone')
const fs = require('node:fs')
const path = require('node:path')

const urlSchema = {
  oneOf: [
    { type: 'string' },
    {
      type: 'object',
      properties: {
        protocol: { type: 'string' },
        hostname: { type: 'string' },
        pathname: { type: 'string' }
        // port type => any
        // query type => any
      },
      additionalProperties: true,
      required: ['pathname']
    }
  ]
}

const schema = {
  type: 'object',
  properties: {
    url: urlSchema,
    path: urlSchema,
    cookies: {
      type: 'object',
      additionalProperties: true
    },
    headers: {
      type: 'object',
      additionalProperties: true
    },
    query: {
      anyOf: [
        {
          type: 'object',
          additionalProperties: true
        },
        {
          type: 'string'
        }
      ]
    },
    simulate: {
      type: 'object',
      properties: {
        end: { type: 'boolean' },
        split: { type: 'boolean' },
        error: { type: 'boolean' },
        close: { type: 'boolean' }
      }
    },
    authority: { type: 'string' },
    remoteAddress: { type: 'string' },
    method: { type: 'string', enum: http.METHODS.concat(http.METHODS.map(toLowerCase)) },
    validate: { type: 'boolean' }
    // payload type => any
  },
  additionalProperties: true,
  oneOf: [
    { required: ['url'] },
    { required: ['path'] }
  ]
}

function toLowerCase (m) { return m.toLowerCase() }

const factory = AjvStandaloneCompiler({
  readMode: false,
  storeFunction (routeOpts, schemaValidationCode) {
    const moduleCode = `// This file is autogenerated by ${__filename.replace(__dirname, 'build')}, do not edit
/* c8 ignore start */
/* eslint-disable */
${schemaValidationCode}
`
    const file = path.join(__dirname, '..', 'lib', 'config-validator.js')
    fs.writeFileSync(file, moduleCode)
    console.log(`Saved ${file} file successfully`)
  }
})

const compiler = factory({}, {
  customOptions: {
    code: {
      source: true,
      lines: true,
      optimize: 3
    },
    removeAdditional: true,
    coerceTypes: true
  }
})

compiler({ schema })
