{-# LANGUAGE DataKinds        #-}
{-# LANGUAGE DeriveGeneric    #-}
{-# LANGUAGE TypeApplications #-}

module HaskellWorks.Simd.Cli.ChunkData where

import Control.Lens
import Data.Generics.Product.Any
import GHC.Generics

import qualified Data.ByteString as BS
import qualified Data.Map        as M

data ChunkData = ChunkData
  { ChunkData -> Int
count :: Int
  , ChunkData -> Map Int Int
sizes :: M.Map Int Int
  } deriving (Int -> ChunkData -> ShowS
[ChunkData] -> ShowS
ChunkData -> String
(Int -> ChunkData -> ShowS)
-> (ChunkData -> String)
-> ([ChunkData] -> ShowS)
-> Show ChunkData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ChunkData] -> ShowS
$cshowList :: [ChunkData] -> ShowS
show :: ChunkData -> String
$cshow :: ChunkData -> String
showsPrec :: Int -> ChunkData -> ShowS
$cshowsPrec :: Int -> ChunkData -> ShowS
Show, (forall x. ChunkData -> Rep ChunkData x)
-> (forall x. Rep ChunkData x -> ChunkData) -> Generic ChunkData
forall x. Rep ChunkData x -> ChunkData
forall x. ChunkData -> Rep ChunkData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ChunkData x -> ChunkData
$cfrom :: forall x. ChunkData -> Rep ChunkData x
Generic)

instance Semigroup ChunkData where
  ChunkData
a <> :: ChunkData -> ChunkData -> ChunkData
<> ChunkData
b = ChunkData :: Int -> Map Int Int -> ChunkData
ChunkData
    { count :: Int
count = ChunkData
a ChunkData -> Getting Int ChunkData Int -> Int
forall s a. s -> Getting a s a -> a
^. forall k (sel :: k) s t a b. HasAny sel s t a b => Lens s t a b
forall s t a b. HasAny "count" s t a b => Lens s t a b
the @"count" Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ChunkData
b ChunkData -> Getting Int ChunkData Int -> Int
forall s a. s -> Getting a s a -> a
^. forall k (sel :: k) s t a b. HasAny sel s t a b => Lens s t a b
forall s t a b. HasAny "count" s t a b => Lens s t a b
the @"count"
    , sizes :: Map Int Int
sizes = (Int -> Int -> Int) -> Map Int Int -> Map Int Int -> Map Int Int
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
M.unionWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) (ChunkData
a ChunkData
-> Getting (Map Int Int) ChunkData (Map Int Int) -> Map Int Int
forall s a. s -> Getting a s a -> a
^. forall k (sel :: k) s t a b. HasAny sel s t a b => Lens s t a b
forall s t a b. HasAny "sizes" s t a b => Lens s t a b
the @"sizes") (ChunkData
b ChunkData
-> Getting (Map Int Int) ChunkData (Map Int Int) -> Map Int Int
forall s a. s -> Getting a s a -> a
^. forall k (sel :: k) s t a b. HasAny sel s t a b => Lens s t a b
forall s t a b. HasAny "sizes" s t a b => Lens s t a b
the @"sizes")
    }

instance Monoid ChunkData where
  mempty :: ChunkData
mempty = Int -> Map Int Int -> ChunkData
ChunkData Int
0 Map Int Int
forall k a. Map k a
M.empty

chunkDataOf :: BS.ByteString -> ChunkData
chunkDataOf :: ByteString -> ChunkData
chunkDataOf ByteString
bs = ChunkData :: Int -> Map Int Int -> ChunkData
ChunkData
  { count :: Int
count = Int
1
  , sizes :: Map Int Int
sizes = Int -> Int -> Map Int Int
forall k a. k -> a -> Map k a
M.singleton (ByteString -> Int
BS.length ByteString
bs) Int
1
  }