/**
 * Threshold Validator
 *
 * Custom validator for MPC threshold configuration validation.
 */

import {
  ValidatorConstraint,
  ValidatorConstraintInterface,
  ValidationArguments,
  registerDecorator,
  ValidationOptions,
} from 'class-validator';

export interface ThresholdValidatorOptions {
  minT?: number;
  maxN?: number;
}

@ValidatorConstraint({ name: 'isThreshold', async: false })
export class IsThresholdConstraint implements ValidatorConstraintInterface {
  validate(value: { n: number; t: number }, args: ValidationArguments): boolean {
    if (!value || typeof value !== 'object') {
      return false;
    }

    const { n, t } = value;
    const options = (args.constraints[0] || {}) as ThresholdValidatorOptions;
    const minT = options.minT ?? 2;
    const maxN = options.maxN ?? 10;

    // Basic validation
    if (!Number.isInteger(n) || !Number.isInteger(t)) {
      return false;
    }

    // Value bounds
    if (n <= 0 || t <= 0) {
      return false;
    }

    // t cannot exceed n
    if (t > n) {
      return false;
    }

    // Security: t must be at least minT
    if (t < minT) {
      return false;
    }

    // Practical limit: n cannot exceed maxN
    if (n > maxN) {
      return false;
    }

    return true;
  }

  defaultMessage(args: ValidationArguments): string {
    const options = (args.constraints[0] || {}) as ThresholdValidatorOptions;
    const minT = options.minT ?? 2;
    const maxN = options.maxN ?? 10;
    return `Threshold must satisfy: t >= ${minT}, n <= ${maxN}, and t <= n`;
  }
}

/**
 * Decorator for Threshold validation
 */
export function IsThreshold(
  options?: ThresholdValidatorOptions,
  validationOptions?: ValidationOptions,
) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [options],
      validator: IsThresholdConstraint,
    });
  };
}
