{-# LANGUAGE OverloadedStrings #-}

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

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

Reflection.
-}

module Network.MPD.Applicative.Reflection
    ( commands
    , notCommands
    , tagTypes
    , urlHandlers
    , decoders
    , config
    ) where

import           Network.MPD.Util
import           Network.MPD.Applicative.Internal
import           Network.MPD.Applicative.Util

import           Control.Applicative
import           Prelude hiding (repeat, read)

import qualified Data.ByteString.UTF8 as UTF8

-- | Get a list of available commands.
commands :: Command [String]
commands :: Command [String]
commands = forall a. Parser a -> [String] -> Command a
Command Parser [String]
p [String
"commands"]
    where
        p :: Parser [String]
p = forall a b. (a -> b) -> [a] -> [b]
map ByteString -> String
UTF8.toString forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
takeValues forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [ByteString]
getResponse

-- | Get a list of unavailable commands (i.e., commands that require
-- an authenticated session).
notCommands :: Command [String]
notCommands :: Command [String]
notCommands = forall a. Parser a -> [String] -> Command a
Command Parser [String]
p [String
"notcommands"]
    where
        p :: Parser [String]
p = forall a b. (a -> b) -> [a] -> [b]
map ByteString -> String
UTF8.toString forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
takeValues forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [ByteString]
getResponse

-- | Get a list of available song metadata.
tagTypes :: Command [String]
tagTypes :: Command [String]
tagTypes = forall a. Parser a -> [String] -> Command a
Command Parser [String]
p [String
"tagtypes"]
    where
        p :: Parser [String]
p = forall a b. (a -> b) -> [a] -> [b]
map ByteString -> String
UTF8.toString forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
takeValues forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [ByteString]
getResponse

-- | Get a list of available URL handlers.
urlHandlers :: Command [String]
urlHandlers :: Command [String]
urlHandlers = forall a. Parser a -> [String] -> Command a
Command Parser [String]
p [String
"urlhandlers"]
    where
        p :: Parser [String]
p = forall a b. (a -> b) -> [a] -> [b]
map ByteString -> String
UTF8.toString forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
takeValues forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [ByteString]
getResponse

-- | Get a list of available decoder plugins, with their supported
-- suffixes and MIME types.
decoders :: Command [(String, [(String, String)])]
decoders :: Command [(String, [(String, String)])]
decoders = forall a. Parser a -> [String] -> Command a
Command Parser [(String, [(String, String)])]
p [String
"decoders"]
    where
        p :: Parser [(String, [(String, String)])]
p = [(ByteString, ByteString)] -> [(String, [(String, String)])]
takeDecoders forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [(ByteString, ByteString)]
toAssocList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [ByteString]
getResponse

        takeDecoders :: [(ByteString, ByteString)] -> [(String, [(String, String)])]
takeDecoders [] = []
        takeDecoders ((ByteString
_, ByteString
m):[(ByteString, ByteString)]
xs) =
            let ([(ByteString, ByteString)]
info, [(ByteString, ByteString)]
rest) = forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
(==) ByteString
"plugin" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(ByteString, ByteString)]
xs
            in (ByteString -> String
UTF8.toString ByteString
m, forall a b. (a -> b) -> [a] -> [b]
map (ByteString, ByteString) -> (String, String)
decodePair [(ByteString, ByteString)]
info) forall a. a -> [a] -> [a]
: [(ByteString, ByteString)] -> [(String, [(String, String)])]
takeDecoders [(ByteString, ByteString)]
rest

-- | Get configuration values of interest to a client.
--
-- Note: only permitted for clients connected via a unix domain
-- socket (aka \"local clients\").
config :: Command [(String, String)]
config :: Command [(String, String)]
config = forall a. Parser a -> [String] -> Command a
Command Parser [(String, String)]
p [String
"config"]
  where
    p :: Parser [(String, String)]
p = forall a b. (a -> b) -> [a] -> [b]
map (\(ByteString
k, ByteString
v) -> (ByteString -> String
UTF8.toString ByteString
k, ByteString -> String
UTF8.toString ByteString
v)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [(ByteString, ByteString)]
toAssocList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [ByteString]
getResponse