/// <reference types="node" />
import EventEmiter from 'events'

declare module "ledown" {
  type ByteRange = [number, number]

  class ByteSheet {
    remaining: ByteRange[]
    downloading: ByteRange[]
    completed: ByteRange[]

    constructor(arg: number | Array<ByteRange[]>)
  }

  class TaskMeta {
    url: string
    createDate: Date
    mimeType: string
    downloadPath: string
    totalBytes: number
    resumable: boolean
    byteSheet: ByteSheet

    constructor(param: {
      url: string
      mimeType: string
      downloadPath: string
      totalBytes: number
      resumable: boolean
      createDate?: number
      refererUrl?: string
      byteSheet?: Array<ByteRange[]>
    })

    progress: number
    completedByteCount: number
    downloadingByteCount: number
    remainingByteCount: number

    toJSONObject(): Object
  }

  type TaskOptions1 = {
    url: string
    referUrl?: string
    downloadDir?: string
    downloadPath: string
  }

  type TaskOptions2 = {
    url: string
    referUrl?: string
    downloadDir: string
    downloadPath?: string
  }

  class Task extends EventEmiter {
    static create(options: TaskOptions1): Promise<Task>
    static create(options: TaskOptions2): Promise<Task>
    static restoreFromFile(path: string): Promise<Task>
    storeToFile(path: string): Promise<void>
    start(numOfThread?: number, windowSize?: number)
    stop(): Promise<void>
    off: typeof EventEmiter.prototype.removeListener
    metadata: TaskMeta
    progress: number
  }

  export = { Task }
}
