module Vulkan.Utils.ShaderQQ.Backend.Glslang
  ( GlslangError
  , GlslangWarning
  , processGlslangMessages
  ) where

import qualified Data.ByteString.Lazy.Char8    as BSL
import           Data.List.Extra
import           System.FilePath

type GlslangError = String
type GlslangWarning = String

processGlslangMessages :: BSL.ByteString -> ([GlslangWarning], [GlslangError])
processGlslangMessages :: ByteString -> ([GlslangWarning], [GlslangWarning])
processGlslangMessages =
  (GlslangWarning
 -> ([GlslangWarning], [GlslangWarning])
 -> ([GlslangWarning], [GlslangWarning]))
-> ([GlslangWarning], [GlslangWarning])
-> [GlslangWarning]
-> ([GlslangWarning], [GlslangWarning])
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr GlslangWarning
-> ([GlslangWarning], [GlslangWarning])
-> ([GlslangWarning], [GlslangWarning])
grep ([], []) ([GlslangWarning] -> ([GlslangWarning], [GlslangWarning]))
-> (ByteString -> [GlslangWarning])
-> ByteString
-> ([GlslangWarning], [GlslangWarning])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GlslangWarning -> Bool) -> [GlslangWarning] -> [GlslangWarning]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (GlslangWarning -> Bool) -> GlslangWarning -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlslangWarning -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) ([GlslangWarning] -> [GlslangWarning])
-> (ByteString -> [GlslangWarning])
-> ByteString
-> [GlslangWarning]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlslangWarning -> [GlslangWarning]
lines (GlslangWarning -> [GlslangWarning])
-> (ByteString -> GlslangWarning) -> ByteString -> [GlslangWarning]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> GlslangWarning
BSL.unpack
 where
  grep :: GlslangWarning
-> ([GlslangWarning], [GlslangWarning])
-> ([GlslangWarning], [GlslangWarning])
grep GlslangWarning
line ([GlslangWarning]
ws, [GlslangWarning]
es) | GlslangWarning
"WARNING: " GlslangWarning -> GlslangWarning -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` GlslangWarning
line = (GlslangWarning -> GlslangWarning
cut GlslangWarning
line GlslangWarning -> [GlslangWarning] -> [GlslangWarning]
forall a. a -> [a] -> [a]
: [GlslangWarning]
ws, [GlslangWarning]
es)
                     | GlslangWarning
"ERROR: " GlslangWarning -> GlslangWarning -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` GlslangWarning
line   = ([GlslangWarning]
ws, GlslangWarning -> GlslangWarning
cut GlslangWarning
line GlslangWarning -> [GlslangWarning] -> [GlslangWarning]
forall a. a -> [a] -> [a]
: [GlslangWarning]
es)
                     | Bool
otherwise                     = ([GlslangWarning]
ws, [GlslangWarning]
es)

  cut :: GlslangWarning -> GlslangWarning
cut GlslangWarning
line = GlslangWarning -> GlslangWarning
takeFileName GlslangWarning
path GlslangWarning -> GlslangWarning -> GlslangWarning
forall a. Semigroup a => a -> a -> a
<> GlslangWarning
msg
    where (GlslangWarning
path, GlslangWarning
msg) = (Char -> Bool)
-> GlslangWarning -> (GlslangWarning, GlslangWarning)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':') (GlslangWarning -> (GlslangWarning, GlslangWarning))
-> (GlslangWarning -> GlslangWarning)
-> GlslangWarning
-> (GlslangWarning, GlslangWarning)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> GlslangWarning -> GlslangWarning
forall a. Int -> [a] -> [a]
drop Int
1 (GlslangWarning -> (GlslangWarning, GlslangWarning))
-> GlslangWarning -> (GlslangWarning, GlslangWarning)
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> GlslangWarning -> GlslangWarning
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
' ') GlslangWarning
line