module Database.Neo4j.Batch.Label where
import Data.Maybe (fromMaybe)
import Data.String (fromString)
import Network.HTTP.Base (urlEncodeVars)
import qualified Data.Aeson as J
import qualified Data.ByteString.Char8 as S
import qualified Data.ByteString.Lazy as L
import qualified Data.Text as T
import qualified Network.HTTP.Types as HT
import qualified Database.Neo4j.Graph as G
import Database.Neo4j.Types
import Database.Neo4j.Batch.Node
import Database.Neo4j.Batch.Types
parseLabelsPath :: J.Value -> T.Text -> NodeUrl
parseLabelsPath j suf = NodeUrl $ let p = tryParseFrom j in fromMaybe p $ T.stripSuffix suf p
getLabels :: NodeBatchIdentifier a => a -> Batch (BatchFuture [Label])
getLabels n = nextState cmd
where cmd = defCmd{cmdMethod = HT.methodGet, cmdPath = path, cmdBody = "", cmdParse = parser}
path = getNodeBatchId n <> "/labels"
parser jn = G.setNodeLabels (parseLabelsPath jn "/labels") (tryParseBody jn)
getNodesByLabelAndProperty :: Label -> Maybe (T.Text, PropertyValue) -> Batch (BatchFuture [Node])
getNodesByLabelAndProperty lbl prop = nextState cmd
where cmd = defCmd{cmdMethod = HT.methodGet, cmdPath = path, cmdBody = "", cmdParse = parser}
path = "/label/" <> lbl <> "/nodes" <> fromString (propUrl prop)
propUrl Nothing = ""
propUrl (Just (name, value)) = '?' : urlEncodeVars [(T.unpack name, lbsToStr $ J.encode value)]
lbsToStr = S.unpack . L.toStrict
parser jn g = foldl (\gacc n -> G.addNodeLabel n lbl (G.addNode n gacc)) g (tryParseBody jn)
addLabels :: NodeBatchIdentifier a => [Label] -> a -> Batch (BatchFuture ())
addLabels lbls n = nextState cmd
where cmd = defCmd{cmdMethod = HT.methodPost, cmdPath = path, cmdBody = J.toJSON lbls, cmdParse = parser}
path = getNodeBatchId n <> "/labels"
parser jn g = let from = parseLabelsPath jn "/labels" in foldl (flip (G.addNodeLabel from)) g lbls
changeLabels :: NodeBatchIdentifier a => [Label] -> a -> Batch (BatchFuture ())
changeLabels lbls n = nextState cmd
where cmd = defCmd{cmdMethod = HT.methodPut, cmdPath = path, cmdBody = J.toJSON lbls, cmdParse = parser}
path = getNodeBatchId n <> "/labels"
parser jn = G.setNodeLabels (parseLabelsPath jn "/labels") lbls
removeLabel :: NodeBatchIdentifier a => Label -> a -> Batch (BatchFuture ())
removeLabel lbl n = nextState cmd
where cmd = defCmd{cmdMethod = HT.methodDelete, cmdPath = path, cmdBody = "", cmdParse = parser}
suffix = "/labels/" <> lbl
path = getNodeBatchId n <> suffix
parser jn = G.deleteNodeLabel (parseLabelsPath jn suffix) lbl