from typing import Sequence
import torch


def _project_anchors(fmap_shape: Sequence[int], stride: int, anchors: torch.Tensor) -> torch.Tensor:
    """
    project the calculated anchors in each (W x H) positions of a feature map.
    Args:
        fmap_shape (Tuple[int, int]): shape of the feature map (W x H)
        stride (int): stride of the feature map (downscale ratio to original image size)
        anchors (torch.Tensor): calculated anchors for a given stride

    Returns:
        torch.Tensor: anchor over all locations of a feature map. Given A anchors, the shape
        would be `(A x H x W, 4)`
    """
    fw, fh = fmap_shape[:2]
    x_mids = (torch.arange(fw) + 0.5) * stride
    y_mids = (torch.arange(fh) + 0.5) * stride
    x_mids = x_mids.repeat(fh, 1).T.flatten()
    y_mids = y_mids.repeat(fw)
    # xy = torch.stack([x_mids, y_mids]).T
    xy = torch.stack([y_mids, x_mids]).T
    xyxy = torch.cat([xy, xy], dim=1)
    # n_pos = xyxy.size(0)

    xyxy = xyxy.repeat_interleave(anchors.size(0), dim=0)
    anchors = anchors.repeat(fw * fh, 1)

    grid_anchors = xyxy + anchors
    return grid_anchors