import { IProperty, Property } from './Property.js'
import { Headers } from '../lib/headers/Headers.js'

/**
 * An array that specializes in keeping HTTP headers data.
 * Unlike the `Headers` class, this can be serialized with the state.
 */
export class HeadersArray extends Array<Property> {
  static fromHeaders(headersStr?: string): HeadersArray {
    const headers = new Headers(headersStr)
    const array = new HeadersArray()
    headers.forEach((value, name, enabled) => {
      const p = Property.String(name, value, enabled)
      array.push(p)
    })
    return array
  }

  static override from(arrayLike: ArrayLike<IProperty>): HeadersArray {
    const arr = Array.from(arrayLike)
    const result = new HeadersArray()
    arr.forEach((item) => result.push(new Property(item)))
    return result
  }

  toHeaders(): Headers {
    const headers = new Headers()
    this.forEach((item) => {
      const header = item as Property
      headers.append(header.name, header.value as string, header.enabled)
    })
    return headers
  }

  /**
   * Overrides native toString to generate the headers string.
   * @returns HTTP headers string.
   */
  override toString(): string {
    const headers = new Headers()
    this.forEach((item) => {
      const header = item as Property
      headers.append(header.name, header.value as string, header.enabled)
    })
    return headers.toString()
  }

  /**
   * @returns The HTTP headers string with `#` marks when the header is disabled
   */
  toRawString(): string {
    const headers = new Headers()
    this.forEach((item) => {
      const header = item as Property
      headers.append(header.name, header.value as string, header.enabled)
    })
    return headers.toRawString()
  }

  toJSON(): IProperty[] {
    return [...this.map((i) => i.toJSON())]
  }
}
