-- Examples:
--
-- |
-- >>> evalState (getPageTest (Nothing, Nothing)) [S3Object "andrew"]
-- ([S3Object {s3ObjectKey = "andrew"}],Nothing)
--
-- >>> evalState (getPageTest (Nothing, Just "a")) [S3Object "andrew"]
-- ([],Nothing)
--
-- >>> evalState (getPageTest (Just "c", Nothing)) [S3Object "andrew"]
-- ([],Nothing)
getPageTest
    :: MonadState [S3Object] m
    => SearchBounds -> m PageResult
getPageTest (startBound,endBound) = do
    allObjects <- get
    let relevantObjects = sort $ filter withinBounds allObjects
    let (thisResult,nextResults) = splitAt 1000 relevantObjects
    if Fold.null nextResults
        then return (thisResult, Nothing)
        else let lastResult = (s3ObjectKey . last) thisResult
             in return (thisResult, Just (lastResult, endBound))
  where
    withinBounds x = afterStartBound x && beforeEndBound x
    afterStartBound x =
        case startBound of
            Nothing -> True
            (Just bound) -> s3ObjectKey x > bound
    beforeEndBound x =
        case endBound of
            Nothing -> True
            (Just bound) -> s3ObjectKey x < bound
getPageTest
    :: MonadState [S3Object] m
    => SearchBounds -> m PageResult
getPageTest (startBound,endBound) = do
    allObjects <- get
    let relevantObjects = sort $ filter withinBounds allObjects
    let (thisResult,nextResults) = splitAt 1000 relevantObjects
    if Fold.null nextResults
        then return (thisResult, Nothing)
        else let lastResult = (s3ObjectKey . last) thisResult
             in return (thisResult, Just (lastResult, endBound))
  where
    withinBounds x = afterStartBound x && beforeEndBound x
    afterStartBound x =
        case startBound of
            Nothing -> True
            (Just bound) -> s3ObjectKey x > bound
    beforeEndBound x =
        case endBound of
            Nothing -> True
            (Just bound) -> s3ObjectKey x < bound
getPageTest (startBound,endBound) = do
    allObjects <- get
    let relevantObjects = sort $ filter withinBounds allObjects
    let (thisResult,nextResults) = splitAt 1000 relevantObjects
    if Fold.null nextResults
        then return (thisResult, Nothing)
        else let lastResult = (s3ObjectKey . last) thisResult
             in return (thisResult, Just (lastResult, endBound))
  where
    withinBounds x = afterStartBound x && beforeEndBound x
    afterStartBound x =
        case startBound of
            Nothing -> True
            (Just bound) -> s3ObjectKey x > bound
    beforeEndBound x =
        case endBound of
            Nothing -> True
            (Just bound) -> s3ObjectKey x < bound