import type { SerialTaskExecuteContext } from '../handler'
import type { PrivateCustomEventName } from '../types'

import { SerialHandler } from '../handler'
import { createEventBus } from '../utils'

const $bus = createEventBus<PrivateCustomEventName>()

class ByteBuffer extends SerialHandler<Blob, Blob> {
  private static MIN_BYTE_SIZE = 60 * 1024

  private static MIN_LOAD_SIZE = 0.1 * 1024

  private lastRemainingByte: Blob = new Blob([])

  public execute(
    context: SerialTaskExecuteContext<Blob, Blob>,
  ): void {
    if (context.isLastExecute) {
      const originalByte = new Blob([this.lastRemainingByte])

      if (originalByte.size > ByteBuffer.MIN_LOAD_SIZE) {
        this.forwardToHandler(originalByte)
      }

      this.lastRemainingByte = new Blob([])
      this.taskCompletedCallback()
    }
    else {
      const originalByte = new Blob([this.lastRemainingByte, context.taskItem.original!])

      if (originalByte.size >= ByteBuffer.MIN_BYTE_SIZE) {
        this.forwardToHandler(originalByte)

        this.lastRemainingByte = new Blob([])
      }
      else {
        this.lastRemainingByte = originalByte
      }
      this.taskCompletedCallback()
    }
  }

  protected onFinish(): void {
    $bus.emit('_byteBufferFinish')
    this.lastRemainingByte = new Blob([])
  }
}

export default ByteBuffer
