{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE InstanceSigs          #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables   #-}

module HaskellWorks.Data.Json.Succinct.Cursor.Internal
  ( JsonCursor(..)
  , jsonCursorPos
  ) where

import qualified Data.ByteString                                            as BS
import qualified Data.ByteString.Char8                                      as BSC
import           Data.ByteString.Internal                                   as BSI
import           Data.String
import qualified Data.Vector.Storable                                       as DVS
import           Data.Word
import           Foreign.ForeignPtr
import           HaskellWorks.Data.Bits.BitShown
import           HaskellWorks.Data.FromByteString
import           HaskellWorks.Data.FromForeignRegion
import qualified HaskellWorks.Data.Json.Succinct.Cursor.BalancedParens      as CBP
import           HaskellWorks.Data.Json.Succinct.Cursor.BlankedJson
import           HaskellWorks.Data.Json.Succinct.Cursor.InterestBits
import           HaskellWorks.Data.Positioning
import qualified HaskellWorks.Data.Succinct.BalancedParens                  as BP
import           HaskellWorks.Data.Succinct.RankSelect.Binary.Basic.Rank0
import           HaskellWorks.Data.Succinct.RankSelect.Binary.Basic.Rank1
import           HaskellWorks.Data.Succinct.RankSelect.Binary.Basic.Select1
import           HaskellWorks.Data.Succinct.RankSelect.Binary.Poppy512
import           HaskellWorks.Data.TreeCursor
import           HaskellWorks.Data.Vector.VectorLike

data JsonCursor t v w = JsonCursor
  { JsonCursor t v w -> t
cursorText     :: !t
  , JsonCursor t v w -> v
interests      :: !v
  , JsonCursor t v w -> w
balancedParens :: !w
  , JsonCursor t v w -> Count
cursorRank     :: !Count
  }
  deriving (JsonCursor t v w -> JsonCursor t v w -> Bool
(JsonCursor t v w -> JsonCursor t v w -> Bool)
-> (JsonCursor t v w -> JsonCursor t v w -> Bool)
-> Eq (JsonCursor t v w)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall t v w.
(Eq t, Eq v, Eq w) =>
JsonCursor t v w -> JsonCursor t v w -> Bool
/= :: JsonCursor t v w -> JsonCursor t v w -> Bool
$c/= :: forall t v w.
(Eq t, Eq v, Eq w) =>
JsonCursor t v w -> JsonCursor t v w -> Bool
== :: JsonCursor t v w -> JsonCursor t v w -> Bool
$c== :: forall t v w.
(Eq t, Eq v, Eq w) =>
JsonCursor t v w -> JsonCursor t v w -> Bool
Eq, Int -> JsonCursor t v w -> ShowS
[JsonCursor t v w] -> ShowS
JsonCursor t v w -> String
(Int -> JsonCursor t v w -> ShowS)
-> (JsonCursor t v w -> String)
-> ([JsonCursor t v w] -> ShowS)
-> Show (JsonCursor t v w)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall t v w.
(Show t, Show v, Show w) =>
Int -> JsonCursor t v w -> ShowS
forall t v w.
(Show t, Show v, Show w) =>
[JsonCursor t v w] -> ShowS
forall t v w.
(Show t, Show v, Show w) =>
JsonCursor t v w -> String
showList :: [JsonCursor t v w] -> ShowS
$cshowList :: forall t v w.
(Show t, Show v, Show w) =>
[JsonCursor t v w] -> ShowS
show :: JsonCursor t v w -> String
$cshow :: forall t v w.
(Show t, Show v, Show w) =>
JsonCursor t v w -> String
showsPrec :: Int -> JsonCursor t v w -> ShowS
$cshowsPrec :: forall t v w.
(Show t, Show v, Show w) =>
Int -> JsonCursor t v w -> ShowS
Show)

instance  (FromBlankedJson (JsonInterestBits a), FromBlankedJson (CBP.JsonBalancedParens b))
          => FromByteString (JsonCursor BS.ByteString a b) where
  fromByteString :: ByteString -> JsonCursor ByteString a b
fromByteString ByteString
bs   = JsonCursor :: forall t v w. t -> v -> w -> Count -> JsonCursor t v w
JsonCursor
    { cursorText :: ByteString
cursorText      = ByteString
bs
    , interests :: a
interests       = JsonInterestBits a -> a
forall a. JsonInterestBits a -> a
getJsonInterestBits (BlankedJson -> JsonInterestBits a
forall a. FromBlankedJson a => BlankedJson -> a
fromBlankedJson BlankedJson
blankedJson)
    , balancedParens :: b
balancedParens  = JsonBalancedParens b -> b
forall a. JsonBalancedParens a -> a
CBP.getJsonBalancedParens (BlankedJson -> JsonBalancedParens b
forall a. FromBlankedJson a => BlankedJson -> a
fromBlankedJson BlankedJson
blankedJson)
    , cursorRank :: Count
cursorRank      = Count
1
    }
    where blankedJson :: BlankedJson
          blankedJson :: BlankedJson
blankedJson = ByteString -> BlankedJson
forall a. FromByteString a => ByteString -> a
fromByteString ByteString
bs

instance IsString (JsonCursor String (BitShown [Bool]) (BP.SimpleBalancedParens [Bool])) where
  fromString :: String -> JsonCursor String (BitShown [Bool]) (BP.SimpleBalancedParens [Bool])
  fromString :: String
-> JsonCursor
     String (BitShown [Bool]) (SimpleBalancedParens [Bool])
fromString String
s = JsonCursor :: forall t v w. t -> v -> w -> Count -> JsonCursor t v w
JsonCursor
    { cursorText :: String
cursorText      = String
s
    , cursorRank :: Count
cursorRank      = Count
1
    , interests :: BitShown [Bool]
interests       = JsonInterestBits (BitShown [Bool]) -> BitShown [Bool]
forall a. JsonInterestBits a -> a
getJsonInterestBits (BlankedJson -> JsonInterestBits (BitShown [Bool])
forall a. FromBlankedJson a => BlankedJson -> a
fromBlankedJson BlankedJson
blankedJson)
    , balancedParens :: SimpleBalancedParens [Bool]
balancedParens  = JsonBalancedParens (SimpleBalancedParens [Bool])
-> SimpleBalancedParens [Bool]
forall a. JsonBalancedParens a -> a
CBP.getJsonBalancedParens (BlankedJson -> JsonBalancedParens (SimpleBalancedParens [Bool])
forall a. FromBlankedJson a => BlankedJson -> a
fromBlankedJson BlankedJson
blankedJson)
    }
    where blankedJson :: BlankedJson
          blankedJson :: BlankedJson
blankedJson = ByteString -> BlankedJson
forall a. FromByteString a => ByteString -> a
fromByteString (String -> ByteString
BSC.pack String
s)

instance IsString (JsonCursor BS.ByteString (BitShown (DVS.Vector Word8)) (BP.SimpleBalancedParens (DVS.Vector Word8))) where
  fromString :: String
-> JsonCursor
     ByteString
     (BitShown (Vector Word8))
     (SimpleBalancedParens (Vector Word8))
fromString = ByteString
-> JsonCursor
     ByteString
     (BitShown (Vector Word8))
     (SimpleBalancedParens (Vector Word8))
forall a. FromByteString a => ByteString -> a
fromByteString (ByteString
 -> JsonCursor
      ByteString
      (BitShown (Vector Word8))
      (SimpleBalancedParens (Vector Word8)))
-> (String -> ByteString)
-> String
-> JsonCursor
     ByteString
     (BitShown (Vector Word8))
     (SimpleBalancedParens (Vector Word8))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

instance IsString (JsonCursor BS.ByteString (BitShown (DVS.Vector Word16)) (BP.SimpleBalancedParens (DVS.Vector Word16))) where
  fromString :: String
-> JsonCursor
     ByteString
     (BitShown (Vector Word16))
     (SimpleBalancedParens (Vector Word16))
fromString = ByteString
-> JsonCursor
     ByteString
     (BitShown (Vector Word16))
     (SimpleBalancedParens (Vector Word16))
forall a. FromByteString a => ByteString -> a
fromByteString (ByteString
 -> JsonCursor
      ByteString
      (BitShown (Vector Word16))
      (SimpleBalancedParens (Vector Word16)))
-> (String -> ByteString)
-> String
-> JsonCursor
     ByteString
     (BitShown (Vector Word16))
     (SimpleBalancedParens (Vector Word16))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

instance IsString (JsonCursor BS.ByteString (BitShown (DVS.Vector Word32)) (BP.SimpleBalancedParens (DVS.Vector Word32))) where
  fromString :: String
-> JsonCursor
     ByteString
     (BitShown (Vector Word32))
     (SimpleBalancedParens (Vector Word32))
fromString = ByteString
-> JsonCursor
     ByteString
     (BitShown (Vector Word32))
     (SimpleBalancedParens (Vector Word32))
forall a. FromByteString a => ByteString -> a
fromByteString (ByteString
 -> JsonCursor
      ByteString
      (BitShown (Vector Word32))
      (SimpleBalancedParens (Vector Word32)))
-> (String -> ByteString)
-> String
-> JsonCursor
     ByteString
     (BitShown (Vector Word32))
     (SimpleBalancedParens (Vector Word32))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

instance IsString (JsonCursor BS.ByteString (BitShown (DVS.Vector Word64)) (BP.SimpleBalancedParens (DVS.Vector Word64))) where
  fromString :: String
-> JsonCursor
     ByteString
     (BitShown (Vector Word64))
     (SimpleBalancedParens (Vector Word64))
fromString = ByteString
-> JsonCursor
     ByteString
     (BitShown (Vector Word64))
     (SimpleBalancedParens (Vector Word64))
forall a. FromByteString a => ByteString -> a
fromByteString (ByteString
 -> JsonCursor
      ByteString
      (BitShown (Vector Word64))
      (SimpleBalancedParens (Vector Word64)))
-> (String -> ByteString)
-> String
-> JsonCursor
     ByteString
     (BitShown (Vector Word64))
     (SimpleBalancedParens (Vector Word64))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

instance IsString (JsonCursor BS.ByteString Poppy512 (BP.SimpleBalancedParens (DVS.Vector Word64))) where
  fromString :: String
-> JsonCursor
     ByteString Poppy512 (SimpleBalancedParens (Vector Word64))
fromString = ByteString
-> JsonCursor
     ByteString Poppy512 (SimpleBalancedParens (Vector Word64))
forall a. FromByteString a => ByteString -> a
fromByteString (ByteString
 -> JsonCursor
      ByteString Poppy512 (SimpleBalancedParens (Vector Word64)))
-> (String -> ByteString)
-> String
-> JsonCursor
     ByteString Poppy512 (SimpleBalancedParens (Vector Word64))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

instance FromForeignRegion (JsonCursor BS.ByteString (BitShown (DVS.Vector Word8)) (BP.SimpleBalancedParens (DVS.Vector Word8))) where
  fromForeignRegion :: ForeignRegion
-> JsonCursor
     ByteString
     (BitShown (Vector Word8))
     (SimpleBalancedParens (Vector Word8))
fromForeignRegion (ForeignPtr Word8
fptr, Int
offset, Int
size) = ByteString
-> JsonCursor
     ByteString
     (BitShown (Vector Word8))
     (SimpleBalancedParens (Vector Word8))
forall a. FromByteString a => ByteString -> a
fromByteString (ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr (ForeignPtr Word8 -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr ForeignPtr Word8
fptr) Int
offset Int
size)

instance FromForeignRegion (JsonCursor BS.ByteString (BitShown (DVS.Vector Word16)) (BP.SimpleBalancedParens (DVS.Vector Word16))) where
  fromForeignRegion :: ForeignRegion
-> JsonCursor
     ByteString
     (BitShown (Vector Word16))
     (SimpleBalancedParens (Vector Word16))
fromForeignRegion (ForeignPtr Word8
fptr, Int
offset, Int
size) = ByteString
-> JsonCursor
     ByteString
     (BitShown (Vector Word16))
     (SimpleBalancedParens (Vector Word16))
forall a. FromByteString a => ByteString -> a
fromByteString (ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr (ForeignPtr Word8 -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr ForeignPtr Word8
fptr) Int
offset Int
size)

instance FromForeignRegion (JsonCursor BS.ByteString (BitShown (DVS.Vector Word32)) (BP.SimpleBalancedParens (DVS.Vector Word32))) where
  fromForeignRegion :: ForeignRegion
-> JsonCursor
     ByteString
     (BitShown (Vector Word32))
     (SimpleBalancedParens (Vector Word32))
fromForeignRegion (ForeignPtr Word8
fptr, Int
offset, Int
size) = ByteString
-> JsonCursor
     ByteString
     (BitShown (Vector Word32))
     (SimpleBalancedParens (Vector Word32))
forall a. FromByteString a => ByteString -> a
fromByteString (ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr (ForeignPtr Word8 -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr ForeignPtr Word8
fptr) Int
offset Int
size)

instance FromForeignRegion (JsonCursor BS.ByteString (BitShown (DVS.Vector Word64)) (BP.SimpleBalancedParens (DVS.Vector Word64))) where
  fromForeignRegion :: ForeignRegion
-> JsonCursor
     ByteString
     (BitShown (Vector Word64))
     (SimpleBalancedParens (Vector Word64))
fromForeignRegion (ForeignPtr Word8
fptr, Int
offset, Int
size) = ByteString
-> JsonCursor
     ByteString
     (BitShown (Vector Word64))
     (SimpleBalancedParens (Vector Word64))
forall a. FromByteString a => ByteString -> a
fromByteString (ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr (ForeignPtr Word8 -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr ForeignPtr Word8
fptr) Int
offset Int
size)

instance FromForeignRegion (JsonCursor BS.ByteString Poppy512 (BP.SimpleBalancedParens (DVS.Vector Word64))) where
  fromForeignRegion :: ForeignRegion
-> JsonCursor
     ByteString Poppy512 (SimpleBalancedParens (Vector Word64))
fromForeignRegion (ForeignPtr Word8
fptr, Int
offset, Int
size) = ByteString
-> JsonCursor
     ByteString Poppy512 (SimpleBalancedParens (Vector Word64))
forall a. FromByteString a => ByteString -> a
fromByteString (ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr (ForeignPtr Word8 -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr ForeignPtr Word8
fptr) Int
offset Int
size)

instance (BP.BalancedParens u, Rank1 u, Rank0 u) => TreeCursor (JsonCursor t v u) where
  firstChild :: JsonCursor t v u -> Maybe (JsonCursor t v u)
  firstChild :: JsonCursor t v u -> Maybe (JsonCursor t v u)
firstChild JsonCursor t v u
k = let mq :: Maybe Count
mq = u -> Count -> Maybe Count
forall v. BalancedParens v => v -> Count -> Maybe Count
BP.firstChild (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k) in (\Count
q -> JsonCursor t v u
k { cursorRank :: Count
cursorRank = Count
q }) (Count -> JsonCursor t v u)
-> Maybe Count -> Maybe (JsonCursor t v u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Count
mq

  nextSibling :: JsonCursor t v u -> Maybe (JsonCursor t v u)
  nextSibling :: JsonCursor t v u -> Maybe (JsonCursor t v u)
nextSibling JsonCursor t v u
k = (\Count
q -> JsonCursor t v u
k { cursorRank :: Count
cursorRank = Count
q }) (Count -> JsonCursor t v u)
-> Maybe Count -> Maybe (JsonCursor t v u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> u -> Count -> Maybe Count
forall v. BalancedParens v => v -> Count -> Maybe Count
BP.nextSibling (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k)

  parent :: JsonCursor t v u -> Maybe (JsonCursor t v u)
  parent :: JsonCursor t v u -> Maybe (JsonCursor t v u)
parent JsonCursor t v u
k = let mq :: Maybe Count
mq = u -> Count -> Maybe Count
forall v. BalancedParens v => v -> Count -> Maybe Count
BP.parent (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k) in (\Count
q -> JsonCursor t v u
k { cursorRank :: Count
cursorRank = Count
q }) (Count -> JsonCursor t v u)
-> Maybe Count -> Maybe (JsonCursor t v u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Count
mq

  depth :: JsonCursor t v u -> Maybe Count
  depth :: JsonCursor t v u -> Maybe Count
depth JsonCursor t v u
k = u -> Count -> Maybe Count
forall v.
(BalancedParens v, Rank0 v, Rank1 v) =>
v -> Count -> Maybe Count
BP.depth (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k)

  subtreeSize :: JsonCursor t v u -> Maybe Count
  subtreeSize :: JsonCursor t v u -> Maybe Count
subtreeSize JsonCursor t v u
k = u -> Count -> Maybe Count
forall v. BalancedParens v => v -> Count -> Maybe Count
BP.subtreeSize (JsonCursor t v u -> u
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor t v u
k) (JsonCursor t v u -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor t v u
k)

jsonCursorPos :: (Rank1 w, Select1 v, VectorLike s) => JsonCursor s v w -> Position
jsonCursorPos :: JsonCursor s v w -> Position
jsonCursorPos JsonCursor s v w
k = Count -> Position
toPosition (v -> Count -> Count
forall v. Select1 v => v -> Count -> Count
select1 v
ik (w -> Count -> Count
forall v. Rank1 v => v -> Count -> Count
rank1 w
bpk (JsonCursor s v w -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor s v w
k)) Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  where ik :: v
ik  = JsonCursor s v w -> v
forall t v w. JsonCursor t v w -> v
interests JsonCursor s v w
k
        bpk :: w
bpk = JsonCursor s v w -> w
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor s v w
k