import math
from typing import List, Optional, Union

import xmod

from old.vl8.util import error

Number = Union[int, float]
Gaps = Union[Number, List[Number]]


@xmod
def fix_gaps(
    durations: List[int],
    gaps: Gaps,
    pre: float = 0,
    post: float = 0,
    sample_rate: Optional[int] = None,
):
    # TODO: fix_gaps should learn about durations amd ration
    if pre < 0 or post < 0:
        raise ValueError("pre and post cannot be negative")

    if not isinstance(gaps, list):
        gaps = [gaps]
    elif not gaps:
        raise ValueError("gap must be a non-empty list or an integer")

    n = len(durations)
    scale = math.ceil(n / len(gaps))
    gaps = [pre] + (gaps * scale)[: n - 1] + [post]

    if sample_rate:
        gaps = [g * sample_rate for g in gaps]

    gaps = [round(g) for g in gaps]

    # Fix any fade gaps that are too long.
    for i, gap in enumerate(gaps):
        if i > 0:
            gap = max(gap, -durations[i - 1])
        if i < n:
            gap = max(gap, -durations[i])
        if gaps[i] != gap:
            error(f"Gap {i}: {gap} was longer than the sample!")
            gaps[i] = gap

    assert len(gaps) == n + 1
    return gaps
