/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2026 metamuffin <metamuffin.org>
*/
/// <reference lib="dom" />
import { OVar } from "../jshelper/mod.ts";

interface Measurement { time: number, duration: number, size: number }
export class SegmentDownloader {
    private measurements: Measurement[] = []

    public bandwidth_avail = new OVar(Infinity)
    public bandwidth_used = new OVar(Infinity)
    public total_downloaded = new OVar(0)

    constructor() { }

    async download(url: string): Promise<ArrayBuffer> {
        const dl_start = performance.now();
        const res = await fetch(url)
        const dl_header = performance.now();
        if (!res.ok) throw new Error("aaaaaa");
        const buf = await res.arrayBuffer()
        const dl_body = performance.now();

        this.total_downloaded.value += buf.byteLength
        if (buf.byteLength > 100 * 1000) {
            const m = {
                time: dl_start,
                duration: (dl_body - dl_header) / 1000,
                size: buf.byteLength
            }
            this.measurements.push(m)
            this.update_bandwidth()
        }
        return buf;
    }

    update_bandwidth() {
        while (this.measurements.length > 32)
            this.measurements.splice(0, 1)
        const total_elapsed = (performance.now() - this.measurements.reduce((a, v) => Math.min(a, v.time), 0)) / 1000;
        const total_size = this.measurements.reduce((a, v) => v.size + a, 0)
        const total_duration = this.measurements.reduce((a, v) => v.duration + a, 0)
        this.bandwidth_avail.value = total_size / total_duration
        this.bandwidth_used.value = total_size / total_elapsed
    }
}
