/* eslint-disable @typescript-eslint/unified-signatures */
import { HttpStep, IHttpStep } from '../../HttpStep.js'

export const ReadValueStepKind = 'HttpAction#ReadValue'

/**
 * Reads the value for a given path from the input data. This works with the `ReadDataSourceStep`.
 */
export interface IReadValueStep extends IHttpStep {
  kind: typeof ReadValueStepKind
  /**
   * The path to the data.
   * For JSON value use https://jmespath.org/ syntax.
   * For XML use xpath.
   * For any other use a simple path to the data separated by dot (e.g. headers.content-type)
   */
  path?: string
}

/**
 * Reads the value for a given path from the input data. This works with the `ReadDataSourceStep`.
 */
export class ReadValueStep extends HttpStep {
  override kind = ReadValueStepKind

  /**
   * The path to the data.
   * For JSON value use https://jmespath.org/ syntax.
   * For XML use xpath.
   * For any other use a simple path to the data separated by dot (e.g. headers.content-type)
   */
  path?: string

  /**
   * Creates the step from values.
   * @param path The path to the data.
   */
  constructor(path: string)

  /**
   * Creates the step from serialized schema.
   * @param init The serialized step values.
   */
  constructor(init: IReadValueStep)

  /**
   * Creates an empty step.
   */
  constructor()

  constructor(pathOrInit?: string | IReadValueStep) {
    super()
    if (!pathOrInit) {
      return
    }
    if (typeof pathOrInit === 'object') {
      const typed = pathOrInit as IReadValueStep
      this.new(typed)
    } else if (typeof pathOrInit === 'string') {
      this.new({
        kind: ReadValueStepKind,
        path: pathOrInit,
        enabled: true,
      })
    }
  }

  override new(init: IReadValueStep): void {
    super.new(init)
    this.kind = ReadValueStepKind
    this.path = init.path
  }

  checkValidity(): boolean {
    const { path } = this
    return !!path
  }

  override toJSON(): IReadValueStep {
    const result: IReadValueStep = {
      ...super.toJSON(),
      kind: ReadValueStepKind,
    }
    if (this.path) {
      result.path = this.path
    }
    return result
  }
}
