module Hadolint.Formatter.Format
  ( severityText,
    stripNewlines,
    errorMessageLine,
    errorPosition,
    errorPositionPretty,
    Text.Megaparsec.Error.errorBundlePretty,
    Result (..),
    toResult,
  )
where

import qualified Data.List.NonEmpty as NE
import Data.Sequence (Seq)
import qualified Data.Sequence as Seq
import qualified Data.Text as Text
import qualified Hadolint.Rule
import Text.Megaparsec (TraversableStream (..), pstateSourcePos)
import Text.Megaparsec.Error
import Text.Megaparsec.Pos (SourcePos, sourcePosPretty)
import Text.Megaparsec.Stream (VisualStream)

data Result s e = Result
  { Result s e -> Text
fileName :: Text.Text,
    Result s e -> Seq (ParseErrorBundle s e)
errors :: Seq (ParseErrorBundle s e),
    Result s e -> Failures
checks :: Hadolint.Rule.Failures
  }

toResult :: Text.Text -> Either (ParseErrorBundle s e) Hadolint.Rule.Failures -> Result s e
toResult :: Text -> Either (ParseErrorBundle s e) Failures -> Result s e
toResult Text
file Either (ParseErrorBundle s e) Failures
res =
  case Either (ParseErrorBundle s e) Failures
res of
    Left ParseErrorBundle s e
err -> Text -> Seq (ParseErrorBundle s e) -> Failures -> Result s e
forall s e.
Text -> Seq (ParseErrorBundle s e) -> Failures -> Result s e
Result Text
file (ParseErrorBundle s e -> Seq (ParseErrorBundle s e)
forall a. a -> Seq a
Seq.singleton ParseErrorBundle s e
err) Failures
forall a. Monoid a => a
mempty
    Right Failures
c -> Text -> Seq (ParseErrorBundle s e) -> Failures -> Result s e
forall s e.
Text -> Seq (ParseErrorBundle s e) -> Failures -> Result s e
Result Text
file Seq (ParseErrorBundle s e)
forall a. Monoid a => a
mempty (Failures -> Failures
forall a. Ord a => Seq a -> Seq a
Seq.unstableSort Failures
c)

severityText :: Hadolint.Rule.DLSeverity -> Text.Text
severityText :: DLSeverity -> Text
severityText DLSeverity
s =
  case DLSeverity
s of
    DLSeverity
Hadolint.Rule.DLErrorC -> Text
"error"
    DLSeverity
Hadolint.Rule.DLWarningC -> Text
"warning"
    DLSeverity
Hadolint.Rule.DLInfoC -> Text
"info"
    DLSeverity
Hadolint.Rule.DLStyleC -> Text
"style"
    DLSeverity
_ -> Text
""

stripNewlines :: String -> String
stripNewlines :: String -> String
stripNewlines =
  (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map
    ( \Char
c ->
        if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n'
          then Char
' '
          else Char
c
    )

errorMessageLine :: (VisualStream s, TraversableStream s, ShowErrorComponent e) => ParseErrorBundle s e -> String
errorMessageLine :: ParseErrorBundle s e -> String
errorMessageLine err :: ParseErrorBundle s e
err@(ParseErrorBundle NonEmpty (ParseError s e)
e PosState s
_) =
  ParseErrorBundle s e -> String
forall s e. TraversableStream s => ParseErrorBundle s e -> String
errorPositionPretty ParseErrorBundle s e
err String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ParseError s e -> String
forall s e.
(VisualStream s, ShowErrorComponent e) =>
ParseError s e -> String
parseErrorTextPretty (NonEmpty (ParseError s e) -> ParseError s e
forall a. NonEmpty a -> a
NE.head NonEmpty (ParseError s e)
e)

errorPositionPretty :: TraversableStream s => ParseErrorBundle s e -> String
errorPositionPretty :: ParseErrorBundle s e -> String
errorPositionPretty ParseErrorBundle s e
err = SourcePos -> String
sourcePosPretty (ParseErrorBundle s e -> SourcePos
forall s e.
TraversableStream s =>
ParseErrorBundle s e -> SourcePos
errorPosition ParseErrorBundle s e
err)

errorPosition :: TraversableStream s => ParseErrorBundle s e -> Text.Megaparsec.Pos.SourcePos
errorPosition :: ParseErrorBundle s e -> SourcePos
errorPosition (ParseErrorBundle NonEmpty (ParseError s e)
e PosState s
s) =
  let (Maybe String
_, PosState s
posState) = Int -> PosState s -> (Maybe String, PosState s)
forall s.
TraversableStream s =>
Int -> PosState s -> (Maybe String, PosState s)
reachOffset (ParseError s e -> Int
forall s e. ParseError s e -> Int
errorOffset (NonEmpty (ParseError s e) -> ParseError s e
forall a. NonEmpty a -> a
NE.head NonEmpty (ParseError s e)
e)) PosState s
s
   in PosState s -> SourcePos
forall s. PosState s -> SourcePos
pstateSourcePos PosState s
posState