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

module HaskellWorks.Data.Json.Succinct.PartialIndex where

import           Control.Arrow
import qualified Data.ByteString                                            as BS
import qualified Data.List                                                  as L
import           HaskellWorks.Data.Bits.BitWise
import           HaskellWorks.Data.Json.CharLike
import           HaskellWorks.Data.Json.Succinct
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.TreeCursor
import           HaskellWorks.Data.Vector.VectorLike

data JsonPartialIndex
  = JsonPartialIndexString BS.ByteString
  | JsonPartialIndexNumber BS.ByteString
  | JsonPartialIndexObject [(BS.ByteString, JsonPartialIndex)]
  | JsonPartialIndexArray [JsonPartialIndex]
  | JsonPartialIndexBool Bool
  | JsonPartialIndexNull
  | JsonPartialIndexError String
  deriving (JsonPartialIndex -> JsonPartialIndex -> Bool
(JsonPartialIndex -> JsonPartialIndex -> Bool)
-> (JsonPartialIndex -> JsonPartialIndex -> Bool)
-> Eq JsonPartialIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JsonPartialIndex -> JsonPartialIndex -> Bool
$c/= :: JsonPartialIndex -> JsonPartialIndex -> Bool
== :: JsonPartialIndex -> JsonPartialIndex -> Bool
$c== :: JsonPartialIndex -> JsonPartialIndex -> Bool
Eq, Int -> JsonPartialIndex -> ShowS
[JsonPartialIndex] -> ShowS
JsonPartialIndex -> String
(Int -> JsonPartialIndex -> ShowS)
-> (JsonPartialIndex -> String)
-> ([JsonPartialIndex] -> ShowS)
-> Show JsonPartialIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JsonPartialIndex] -> ShowS
$cshowList :: [JsonPartialIndex] -> ShowS
show :: JsonPartialIndex -> String
$cshow :: JsonPartialIndex -> String
showsPrec :: Int -> JsonPartialIndex -> ShowS
$cshowsPrec :: Int -> JsonPartialIndex -> ShowS
Show)

class JsonPartialIndexAt a where
  jsonPartialIndexAt :: a -> JsonPartialIndex

instance (BP.BalancedParens w, Rank0 w, Rank1 w, Select1 v, TestBit w) => JsonPartialIndexAt (JsonCursor BS.ByteString v w) where
  jsonPartialIndexAt :: JsonCursor ByteString v w -> JsonPartialIndex
jsonPartialIndexAt JsonCursor ByteString v w
k = case ByteString -> Maybe (Elem ByteString, ByteString)
forall v. Seq v => v -> Maybe (Elem v, v)
vUncons ByteString
remainder of
    Just (!Elem ByteString
c, ByteString
_) | Word8 -> Bool
forall c. JsonCharLike c => c -> Bool
isLeadingDigit2 Word8
Elem ByteString
c  -> ByteString -> JsonPartialIndex
JsonPartialIndexNumber  ByteString
remainder
    Just (!Elem ByteString
c, ByteString
_) | Word8 -> Bool
forall c. JsonCharLike c => c -> Bool
isQuotDbl Word8
Elem ByteString
c        -> ByteString -> JsonPartialIndex
JsonPartialIndexString  ByteString
remainder
    Just (!Elem ByteString
c, ByteString
_) | Word8 -> Bool
forall c. JsonCharLike c => c -> Bool
isChar_t Word8
Elem ByteString
c         -> Bool -> JsonPartialIndex
JsonPartialIndexBool    Bool
True
    Just (!Elem ByteString
c, ByteString
_) | Word8 -> Bool
forall c. JsonCharLike c => c -> Bool
isChar_f Word8
Elem ByteString
c         -> Bool -> JsonPartialIndex
JsonPartialIndexBool    Bool
False
    Just (!Elem ByteString
c, ByteString
_) | Word8 -> Bool
forall c. JsonCharLike c => c -> Bool
isChar_n Word8
Elem ByteString
c         -> JsonPartialIndex
JsonPartialIndexNull
    Just (!Elem ByteString
c, ByteString
_) | Word8 -> Bool
forall c. JsonCharLike c => c -> Bool
isBraceLeft Word8
Elem ByteString
c      -> [(ByteString, JsonPartialIndex)] -> JsonPartialIndex
JsonPartialIndexObject (Maybe (JsonCursor ByteString v w)
-> [(ByteString, JsonPartialIndex)]
mapValuesFrom   (JsonCursor ByteString v w -> Maybe (JsonCursor ByteString v w)
forall k. TreeCursor k => k -> Maybe k
firstChild JsonCursor ByteString v w
k))
    Just (!Elem ByteString
c, ByteString
_) | Word8 -> Bool
forall c. JsonCharLike c => c -> Bool
isBracketLeft Word8
Elem ByteString
c    -> [JsonPartialIndex] -> JsonPartialIndex
JsonPartialIndexArray  (Maybe (JsonCursor ByteString v w) -> [JsonPartialIndex]
arrayValuesFrom (JsonCursor ByteString v w -> Maybe (JsonCursor ByteString v w)
forall k. TreeCursor k => k -> Maybe k
firstChild JsonCursor ByteString v w
k))
    Just (Elem ByteString, ByteString)
_                            -> String -> JsonPartialIndex
JsonPartialIndexError String
"Invalid Json Type"
    Maybe (Elem ByteString, ByteString)
Nothing                           -> String -> JsonPartialIndex
JsonPartialIndexError String
"End of data"
    where ik :: v
ik                = JsonCursor ByteString v w -> v
forall t v w. JsonCursor t v w -> v
interests JsonCursor ByteString v w
k
          bpk :: w
bpk               = JsonCursor ByteString v w -> w
forall t v w. JsonCursor t v w -> w
balancedParens JsonCursor ByteString v w
k
          p :: Position
p                 = Count -> Position
lastPositionOf (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 ByteString v w -> Count
forall t v w. JsonCursor t v w -> Count
cursorRank JsonCursor ByteString v w
k)))
          remainder :: ByteString
remainder         = Count -> ByteString -> ByteString
forall v. Seq v => Count -> v -> v
vDrop (Position -> Count
toCount Position
p) (JsonCursor ByteString v w -> ByteString
forall t v w. JsonCursor t v w -> t
cursorText JsonCursor ByteString v w
k)
          arrayValuesFrom :: Maybe (JsonCursor BS.ByteString v w) -> [JsonPartialIndex]
          arrayValuesFrom :: Maybe (JsonCursor ByteString v w) -> [JsonPartialIndex]
arrayValuesFrom = (Maybe (JsonCursor ByteString v w)
 -> Maybe (JsonPartialIndex, Maybe (JsonCursor ByteString v w)))
-> Maybe (JsonCursor ByteString v w) -> [JsonPartialIndex]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
L.unfoldr ((JsonCursor ByteString v w
 -> (JsonPartialIndex, Maybe (JsonCursor ByteString v w)))
-> Maybe (JsonCursor ByteString v w)
-> Maybe (JsonPartialIndex, Maybe (JsonCursor ByteString v w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (JsonCursor ByteString v w -> JsonPartialIndex
forall a. JsonPartialIndexAt a => a -> JsonPartialIndex
jsonPartialIndexAt (JsonCursor ByteString v w -> JsonPartialIndex)
-> (JsonCursor ByteString v w -> Maybe (JsonCursor ByteString v w))
-> JsonCursor ByteString v w
-> (JsonPartialIndex, Maybe (JsonCursor ByteString v w))
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& JsonCursor ByteString v w -> Maybe (JsonCursor ByteString v w)
forall k. TreeCursor k => k -> Maybe k
nextSibling))
          mapValuesFrom :: Maybe (JsonCursor ByteString v w)
-> [(ByteString, JsonPartialIndex)]
mapValuesFrom Maybe (JsonCursor ByteString v w)
j   = [JsonPartialIndex] -> [(JsonPartialIndex, JsonPartialIndex)]
forall b. [b] -> [(b, b)]
pairwise (Maybe (JsonCursor ByteString v w) -> [JsonPartialIndex]
arrayValuesFrom Maybe (JsonCursor ByteString v w)
j) [(JsonPartialIndex, JsonPartialIndex)]
-> ((JsonPartialIndex, JsonPartialIndex)
    -> [(ByteString, JsonPartialIndex)])
-> [(ByteString, JsonPartialIndex)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (JsonPartialIndex, JsonPartialIndex)
-> [(ByteString, JsonPartialIndex)]
forall b. (JsonPartialIndex, b) -> [(ByteString, b)]
asField
          pairwise :: [b] -> [(b, b)]
pairwise (b
a:b
b:[b]
rs) = (b
a, b
b) (b, b) -> [(b, b)] -> [(b, b)]
forall a. a -> [a] -> [a]
: [b] -> [(b, b)]
pairwise [b]
rs
          pairwise [b]
_        = []
          asField :: (JsonPartialIndex, b) -> [(ByteString, b)]
asField (JsonPartialIndex
a, b
b)    = case JsonPartialIndex
a of
                                JsonPartialIndexString ByteString
s -> [(ByteString
s, b
b)]
                                JsonPartialIndex
_                 -> []