    -- | Maintainer: 2016 Evan Cofsky <evan@theunixman.com>
    --
    -- Functions running zfs processes.

    module Propellor.Property.ZFS.Process where

    import Propellor.Base
    import Utility.Split

    import Data.List

    -- | Gets the properties of a ZFS volume.
    zfsGetProperties ::  ZFS -> IO ZFSProperties
    zfsGetProperties :: ZFS -> IO ZFSProperties
    zfsGetProperties ZFS
    z =
    	let plist :: [[Char]] -> ZFSProperties
    plist = [([Char], [Char])] -> ZFSProperties
    fromPropertyList ([([Char], [Char])] -> ZFSProperties)
    -> ([[Char]] -> [([Char], [Char])]) -> [[Char]] -> ZFSProperties
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([[Char]] -> Maybe ([Char], [Char]))
    -> [[[Char]]] -> [([Char], [Char])]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe [[Char]] -> Maybe ([Char], [Char])
    forall {b}. [b] -> Maybe (b, b)
    parse ([[[Char]]] -> [([Char], [Char])])
    -> ([[Char]] -> [[[Char]]]) -> [[Char]] -> [([Char], [Char])]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (([Char] -> [[Char]]) -> [[Char]] -> [[[Char]]]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Char] -> [Char] -> [[Char]]
    forall a. Eq a => [a] -> [a] -> [[a]]
    split [Char]
    "\t"))
    	in [[Char]] -> ZFSProperties
    plist ([[Char]] -> ZFSProperties) -> IO [[Char]] -> IO ZFSProperties
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Char] -> [Maybe [Char]] -> ZFS -> IO [[Char]]
    runZfs [Char]
    "get" [[Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just [Char]
    "-H", [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just [Char]
    "-p", [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just [Char]
    "all"] ZFS
    z
      where
    	parse :: [b] -> Maybe (b, b)
    parse (b
    _:b
    k:b
    v:[b]
    _) = (b, b) -> Maybe (b, b)
    forall a. a -> Maybe a
    Just (b
    k, b
    v)
    	parse [b]
    _ = Maybe (b, b)
    forall a. Maybe a
    Nothing

    zfsExists :: ZFS -> IO Bool
    zfsExists :: ZFS -> IO Bool
    zfsExists ZFS
    z = (Bool -> Bool) -> [Bool] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any Bool -> Bool
    forall a. a -> a
    id ([Bool] -> Bool) -> ([[Char]] -> [Bool]) -> [[Char]] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char] -> Bool) -> [[Char]] -> [Bool]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    isInfixOf (ZFS -> [Char]
    zfsName ZFS
    z))
    	([[Char]] -> Bool) -> IO [[Char]] -> IO Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Char] -> [Maybe [Char]] -> ZFS -> IO [[Char]]
    runZfs [Char]
    "list" [[Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just [Char]
    "-H"] ZFS
    z

    -- | Runs the zfs command with the arguments.
    --
    -- Runs the command with -H which will skip the header line and
    -- separate all fields with tabs.
    --
    -- Replaces Nothing in the argument list with the ZFS pool/dataset.
    runZfs :: String -> [Maybe String] -> ZFS -> IO [String]
    runZfs :: [Char] -> [Maybe [Char]] -> ZFS -> IO [[Char]]
    runZfs [Char]
    cmd [Maybe [Char]]
    args ZFS
    z = [Char] -> [[Char]]
    lines ([Char] -> [[Char]]) -> IO [Char] -> IO [[Char]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ([Char] -> [[Char]] -> IO [Char])
    -> ([Char], [[Char]]) -> IO [Char]
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry [Char] -> [[Char]] -> IO [Char]
    readProcess ([Char] -> [Maybe [Char]] -> ZFS -> ([Char], [[Char]])
    zfsCommand [Char]
    cmd [Maybe [Char]]
    args ZFS
    z)

    -- | Return the ZFS command line suitable for readProcess or cmdProperty.
    zfsCommand :: String -> [Maybe String] -> ZFS -> (String, [String])
    zfsCommand :: [Char] -> [Maybe [Char]] -> ZFS -> ([Char], [[Char]])
    zfsCommand [Char]
    cmd [Maybe [Char]]
    args ZFS
    z = ([Char]
    "zfs", [Char]
    cmd[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :((Maybe [Char] -> [Char]) -> [Maybe [Char]] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Char] -> ([Char] -> [Char]) -> Maybe [Char] -> [Char]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (ZFS -> [Char]
    zfsName ZFS
    z) [Char] -> [Char]
    forall a. a -> a
    id) [Maybe [Char]]
    args))