module MatchSigs.Output
  ( sigDuplicateOutput
  ) where

import           Data.Map.Append.Strict (AppendMap(..))
import qualified Data.Map.Strict as M

import           GHC.Api hiding (count)
import           GHC.Output
import           MatchSigs.ProcessHie (SigMap, MatchedSigs(..))

sigDuplicateOutput :: SigMap -> SDoc
sigDuplicateOutput :: SigMap -> SDoc
sigDuplicateOutput (AppendMap Map [Sig ()] MatchedSigs
sigMap) =
  if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SDoc]
outputLines
     then String -> SDoc
text String
"(No duplicated signatures)"
     else [SDoc] -> SDoc
vcat [SDoc]
outputLines

  where
    outputLines :: [SDoc]
outputLines = forall a b. (a -> b) -> [a] -> [b]
map forall {a}. (a, String, [Name]) -> SDoc
sigLine forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter forall {t :: * -> *} {a} {b} {a}. Foldable t => (a, b, t a) -> Bool
multipleNames
                forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap MatchedSigs -> [([Sig FreeVarIdx], String, [Name])]
getMatchedSigs
                forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [a]
M.elems Map [Sig ()] MatchedSigs
sigMap

    multipleNames :: (a, b, t a) -> Bool
multipleNames (a
_, b
_, t a
names) = forall (t :: * -> *) a. Foldable t => t a -> FreeVarIdx
length t a
names forall a. Ord a => a -> a -> Bool
> FreeVarIdx
1
    sigLine :: (a, String, [Name]) -> SDoc
sigLine (a
_, String
renderedSig, [Name]
names) =
      [SDoc] -> SDoc
vcat
        [ PprColour -> SDoc -> SDoc
coloured PprColour
colCyanFg forall a b. (a -> b) -> a -> b
$ SDoc
dcolon SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
renderedSig
        , FreeVarIdx -> SDoc -> SDoc
nest FreeVarIdx
2 forall a b. (a -> b) -> a -> b
$ FreeVarIdx -> SDoc
count (forall (t :: * -> *) a. Foldable t => t a -> FreeVarIdx
length [Name]
names)
        , [SDoc] -> SDoc
vcat forall a b. (a -> b) -> a -> b
$ Name -> SDoc
printName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
names
        , String -> SDoc
text String
""
        ]

    printName :: Name -> SDoc
printName Name
name =
      let nameDoc :: SDoc
nameDoc = PprColour -> SDoc -> SDoc
coloured PprColour
colYellowFg forall a b. (a -> b) -> a -> b
$ forall a. Outputable a => a -> SDoc
ppr Name
name
          locDoc :: SDoc
locDoc = PprColour -> SDoc -> SDoc
coloured PprColour
colMagentaFg forall b c a. (b -> c) -> (a -> b) -> a -> c
. SDoc -> SDoc
parens forall a b. (a -> b) -> a -> b
$ Name -> SDoc
pprDefinedAt Name
name
       in Char -> SDoc
char Char
'•' SDoc -> SDoc -> SDoc
<+> SDoc
nameDoc SDoc -> SDoc -> SDoc
<+> SDoc
locDoc
    count :: FreeVarIdx -> SDoc
count FreeVarIdx
x = PprColour -> SDoc -> SDoc
coloured PprColour
colCyanFg (FreeVarIdx -> SDoc
int FreeVarIdx
x) SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"matches:"