import { HttpStep, IHttpStep } from '../../HttpStep.js'

export const ToBeAssertionKind = 'HttpAction#ToBeAssertion'

export enum ToBeTypes {
  string = 'string',
  number = 'number',
  boolean = 'boolean',
  object = 'object',
  array = 'array',
}

/**
 * An assertion that makes sure the input is of a specific type (string, number, boolean, object, array).
 */
export interface IToBeAssertion extends IHttpStep {
  kind: typeof ToBeAssertionKind

  /**
   * The type to expect.
   */
  value?: ToBeTypes
}

/**
 * An assertion that makes sure the input is of a specific type (string, number, boolean, object, array).
 */
export class ToBeAssertion extends HttpStep {
  override kind = ToBeAssertionKind

  /**
   * The type to expect.
   */
  value?: ToBeTypes

  constructor(valueOrInit?: IToBeAssertion | ToBeTypes) {
    super()
    if (typeof valueOrInit === 'object') {
      const typed = valueOrInit as IToBeAssertion
      this.new(typed)
    } else if (typeof valueOrInit === 'string') {
      this.new({
        kind: ToBeAssertionKind,
        value: valueOrInit,
        enabled: true,
      })
    }
  }

  override new(init: IToBeAssertion): void {
    super.new(init)
    this.kind = ToBeAssertionKind
    this.value = init.value
  }

  checkValidity(): boolean {
    return !!this.value
  }

  override toJSON(): IToBeAssertion {
    const result: IToBeAssertion = {
      ...super.toJSON(),
      kind: ToBeAssertionKind,
    }
    if (this.value) {
      result.value = this.value
    }
    return result
  }
}
