    {-# LANGUAGE OverloadedStrings #-}

    {- |
    Module      : Network.MPD.Applicative.Mount
    Copyright   : (c) Joachim Fasting 2014
    License     : MIT

    Maintainer  : joachifm@fastmail.fm
    Stability   : stable
    Portability : unportable

    Mounting remote storage.
    -}

    module Network.MPD.Applicative.Mount
      ( mount
      , unmount
      , listMounts
      , listNeighbors
      ) where

    import           Network.MPD.Commands.Arg hiding (Command)
    import           Network.MPD.Applicative.Internal
    import           Network.MPD.Util

    import           Data.ByteString.Char8 (ByteString)
    import qualified Data.ByteString.UTF8 as UTF8

    mount :: String -- Path
          -> String -- Uri
          -> Command ()
    mount :: String -> String -> Command ()
    mount String
    p String
    u = Parser () -> [String] -> Command ()
    forall a. Parser a -> [String] -> Command a
    Command Parser ()
    emptyResponse [Command
    "mount" Command -> Args -> String
    forall a. MPDArg a => Command -> a -> String
    <@> String
    p String -> String -> Args
    forall a b. (MPDArg a, MPDArg b) => a -> b -> Args
    <++> String
    u]

    unmount :: String -- Path
            -> Command ()
    unmount :: String -> Command ()
    unmount String
    p = Parser () -> [String] -> Command ()
    forall a. Parser a -> [String] -> Command a
    Command Parser ()
    emptyResponse [Command
    "unmount" Command -> String -> String
    forall a. MPDArg a => Command -> a -> String
    <@> String
    p]

    listMounts :: Command [(String, String)] -- (Path, Uri)
    listMounts :: Command [(String, String)]
    listMounts = Parser [(String, String)] -> [String] -> Command [(String, String)]
    forall a. Parser a -> [String] -> Command a
    Command (([ByteString] -> Either String [(String, String)])
    -> Parser [(String, String)]
    forall a. ([ByteString] -> Either String a) -> Parser a
    liftParser [ByteString] -> Either String [(String, String)]
    p) [String
    "listmounts"]
      where
        p :: [ByteString] -> Either String [(String, String)]
    p = ([(ByteString, ByteString)] -> Either String (String, String))
    -> [[(ByteString, ByteString)]] -> Either String [(String, String)]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM [(ByteString, ByteString)] -> Either String (String, String)
    parseMount ([[(ByteString, ByteString)]] -> Either String [(String, String)])
    -> ([ByteString] -> [[(ByteString, ByteString)]])
    -> [ByteString]
    -> Either String [(String, String)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [ByteString]
    -> [(ByteString, ByteString)] -> [[(ByteString, ByteString)]]
    splitGroups [ByteString
    "mount"] ([(ByteString, ByteString)] -> [[(ByteString, ByteString)]])
    -> ([ByteString] -> [(ByteString, ByteString)])
    -> [ByteString]
    -> [[(ByteString, ByteString)]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [ByteString] -> [(ByteString, ByteString)]
    toAssocList
        parseMount :: [(ByteString, ByteString)] -> Either String (String, String)
        parseMount :: [(ByteString, ByteString)] -> Either String (String, String)
    parseMount [(ByteString
    "mount", ByteString
    mo), (ByteString
    "storage", ByteString
    st)] = (String, String) -> Either String (String, String)
    forall a b. b -> Either a b
    Right (ByteString -> String
    UTF8.toString ByteString
    mo, ByteString -> String
    UTF8.toString ByteString
    st)
        parseMount [(ByteString, ByteString)]
    _ = String -> Either String (String, String)
    forall a b. a -> Either a b
    Left String
    "Unexpected result from listMounts"

    listNeighbors :: Command [(String, String)] -- (Uri, Name)
    listNeighbors :: Command [(String, String)]
    listNeighbors = Parser [(String, String)] -> [String] -> Command [(String, String)]
    forall a. Parser a -> [String] -> Command a
    Command (([ByteString] -> Either String [(String, String)])
    -> Parser [(String, String)]
    forall a. ([ByteString] -> Either String a) -> Parser a
    liftParser [ByteString] -> Either String [(String, String)]
    p) [String
    "listneighbors"]
      where
        p :: [ByteString] -> Either String [(String, String)]
    p = ([(ByteString, ByteString)] -> Either String (String, String))
    -> [[(ByteString, ByteString)]] -> Either String [(String, String)]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM [(ByteString, ByteString)] -> Either String (String, String)
    parseNeighbor ([[(ByteString, ByteString)]] -> Either String [(String, String)])
    -> ([ByteString] -> [[(ByteString, ByteString)]])
    -> [ByteString]
    -> Either String [(String, String)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [ByteString]
    -> [(ByteString, ByteString)] -> [[(ByteString, ByteString)]]
    splitGroups [ByteString
    "neighbor"] ([(ByteString, ByteString)] -> [[(ByteString, ByteString)]])
    -> ([ByteString] -> [(ByteString, ByteString)])
    -> [ByteString]
    -> [[(ByteString, ByteString)]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [ByteString] -> [(ByteString, ByteString)]
    toAssocList
        parseNeighbor :: [(ByteString, ByteString)] -> Either String (String, String)
        parseNeighbor :: [(ByteString, ByteString)] -> Either String (String, String)
    parseNeighbor [(ByteString
    "neighbor", ByteString
    ne), (ByteString
    "name", ByteString
    na)] = (String, String) -> Either String (String, String)
    forall a b. b -> Either a b
    Right (ByteString -> String
    UTF8.toString ByteString
    ne, ByteString -> String
    UTF8.toString ByteString
    na)
        parseNeighbor [(ByteString, ByteString)]
    _ = String -> Either String (String, String)
    forall a b. a -> Either a b
    Left String
    "Unexpected result from listNeighbors"