import Joi from "joi";
import type { Format } from "convict";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const coerceString = (v: any): string => v.toString();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const validator = (s: any) => (v: any) => Joi.assert(v, s);

const url = Joi.string().uri({
  scheme: ["http", "https"],
});
const ip = Joi.string().ip({ version: ["ipv4", "ipv6"], cidr: "optional" });

/**
 * Additional configuration value formats for convict.
 *
 * You can use these to achieve richer validation for your configuration.
 */
export const MetamigoConvictFormats: { [index: string]: Format } = {
  positiveInt: {
    name: "positveInt",
    coerce: (n: string): number => Number.parseInt(n, 10),
    validate: validator(Joi.number().positive().integer()),
  },
  port: {
    name: "port",
    coerce: (n: string): number => Number.parseInt(n, 10),
    validate: validator(Joi.number().port()),
  },
  ipaddress: {
    name: "ipaddress",
    coerce: coerceString,
    validate: validator(ip),
  },
  url: {
    name: "url",
    coerce: coerceString,
    validate: validator(url),
  },
  uri: {
    name: "uri",
    coerce: coerceString,
    validate: validator(Joi.string().uri()),
  },
  optionalUri: {
    name: "uri",
    coerce: coerceString,
    validate: validator(Joi.string().uri().allow("")),
  },
  email: {
    name: "email",
    coerce: coerceString,
    validate: validator(Joi.string().email()),
  },
  uuid: {
    name: "uuid",
    coerce: coerceString,
    validate: validator(Joi.string().guid()),
  },
};
