{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Language.Haskell.Brittany.Internal.Transformations.T3_Par where

import Language.Haskell.Brittany.Internal.Prelude
import Language.Haskell.Brittany.Internal.Components.BriDoc



transformSimplifyPar :: BriDoc -> BriDoc
transformSimplifyPar = transformUp $ \case
  -- BDPar BrIndentNone line1 line2 -> Just $ BDLines [line1, line2]
  -- BDPar line indented ->
  --   Just $ BDLines [line, indented]
  -- BDPar ind1 (BDPar ind2 line p1) p2 | ind1==ind2 ->
  --   Just $ BDPar ind1 line (BDLines [p1, p2])

  -- TODO92 is this still necessary? No tests fail, but maybe
  --        performance gets worse.
  x@(BDPar _ (BDPar _ BDPar{} _) _) -> x
  -- this is a combination of other transformations below, the
  -- important one is the next one.
  BDPar ind1 (BDPar ind2 line p1) (BDLines indenteds) ->
    BDPar ind1 line (BDLines (BDEnsureIndent ind2 p1 : indenteds))
  BDPar ind1 (BDPar ind2 line p1) p2 ->
    BDPar ind1 line (BDLines [BDEnsureIndent ind2 p1, p2])
  BDLines [ BDPar BrIndentNone line (BDLines lines) ] ->
    BDLines (line : lines)
  BDLines lines
    | any
      (\case
        BDLines{} -> True
        BDEmpty{} -> True
        _ -> False
      )
      lines
    -> case lines >>= flattenToDocList of
      [] -> BDEmpty
      [x] -> x
      xs -> BDLines xs
   where
    flattenToDocList = \case
      -- note that this is a transformUp, so we create the invariant that
      -- BDLines does not contain BDEmpty or BDLines, but we may assume the
      -- BDLines below are already flattened.
      BDLines xs -> xs
      BDEmpty -> []
      x -> [x]
  BDLines [] -> BDEmpty
  BDLines [x] -> x
  -- BDCols sig cols | BDPar ind line indented <- List.last cols ->
  --   Just $ BDPar ind (BDCols sig (List.init cols ++ [line])) indented
  -- BDPar BrIndentNone line indented ->
  --   Just $ BDLines [line, indented]
  BDEnsureIndent BrIndentNone x -> x
  -- This does not appear to make a difference, but seems the right
  -- thing to do so I added it for now.
  BDEnsureIndent ind (BDPar BrIndentNone line1 (BDLines linesR)) ->
    BDEnsureIndent ind (BDLines (line1 : linesR))
  x -> x
