{-# LANGUAGE NoImplicitPrelude #-}

module Language.Haskell.Brittany.Internal.ToBriDoc.Module where

import qualified Data.Maybe
import qualified Data.Text                     as Text
import           GHC                            ( ModuleName
                                                , moduleNameString
                                                , unLoc
                                                )
import           GHC.Hs

import           Language.Haskell.Brittany.Internal.Components.BriDoc
import           Language.Haskell.Brittany.Internal.Config.Types
import           Language.Haskell.Brittany.Internal.Prelude
import           Language.Haskell.Brittany.Internal.ToBriDocTools
import           Language.Haskell.Brittany.Internal.Types



moduleNameExportBridoc
  :: EpAnn AnnsModule
  -> LocatedA ModuleName
  -> Maybe (LocatedL [LIE GhcPs])
  -> ToBriDocM BriDocNumbered
moduleNameExportBridoc epAnn modName les = do
  let posModule  = obtainAnnPos epAnn AnnModule
  let posWhere   = obtainAnnPos epAnn AnnWhere
  allowSingleLineExportList <-
    mAsk <&> _conf_layout .> _lconfig_allowSingleLineExportList .> confUnpack
  let allowSingleLine = allowSingleLineExportList || Data.Maybe.isNothing les
  -- the config should not prevent single-line layout when there is no
  -- export list
  let tn              = Text.pack $ moduleNameString $ unLoc modName
  let startDelta = obtainAnnDeltaPos epAnn AnnModule
  -- tellDebugMess (show startDelta)
  let wrapModule = case startDelta of
        Nothing                  -> id
        Just SameLine{}          -> id
        Just (DifferentLine 0 _) -> id
        Just dp                  -> docAddEntryDelta dp
  layouters <- mAsk
  docHandleComms epAnn $ docHandleComms posModule $ runFilteredAlternative $ do
    addAlternativeCond allowSingleLine $ docSeq
      [ appSep $ wrapModule $ docLit $ Text.pack "module"
      , appSep $ docLit tn
      , docForceSingleline $ appSep $ case les of
        Nothing -> docEmpty
        Just x  -> layout_LLIEs layouters True KeepItemsUnsorted x
      , docSeparator
      , docHandleComms posWhere $ docLit $ Text.pack "where"
      ]
    addAlternative $ docLines
      [ docAddBaseY BrIndentRegular $ docPar
          (docSeq
            [appSep $ wrapModule $ docLit $ Text.pack "module", docLit tn]
          )
          (docSeq
            [ case les of
              Nothing -> docEmpty
              Just x  -> layout_LLIEs layouters False KeepItemsUnsorted x
            , docSeparator
            , docHandleComms posWhere $ docLit $ Text.pack "where"
            ]
          )
      ]

