{-# OPTIONS_GHC -Wno-orphans #-}

module Cardano.Api.Pretty
  ( Ann
  , Doc
  , Pretty (..)
  , ShowOf (..)
  , docToLazyText
  , docToText
  , docToString
  , prettyShow
  , renderBuildable
  , textShow
  , pshow
  , prettyException
  , hsep
  , vsep
  , (<+>)
  , black
  , red
  , green
  , yellow
  , blue
  , magenta
  , cyan
  , white
  )
where

import Cardano.Api.Pretty.Internal.ShowOf

import Cardano.Ledger.BaseTypes qualified as L

import Control.Exception.Safe
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Text.Lazy qualified as TextLazy
import Data.Text.Lazy.Builder qualified as LText
import Formatting.Buildable (Buildable)
import Formatting.Buildable qualified as Build
import Prettyprinter
import Prettyprinter.Render.Terminal

-- | 'Ann' is the prettyprinter annotation for cardano-api and cardano-cli to enable the printing
-- of colored output. This is a type alias for AnsiStyle.
type Ann = AnsiStyle

docToString :: Doc AnsiStyle -> String
docToString :: Doc AnsiStyle -> String
docToString = Doc AnsiStyle -> String
forall a. Show a => a -> String
show

-- | Render a 'Pretty' to a 'String'
prettyShow :: Pretty a => a -> String
prettyShow :: forall a. Pretty a => a -> String
prettyShow = Doc AnsiStyle -> String
docToString (Doc AnsiStyle -> String) -> (a -> Doc AnsiStyle) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc AnsiStyle
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

docToLazyText :: Doc AnsiStyle -> TextLazy.Text
docToLazyText :: Doc AnsiStyle -> Text
docToLazyText = SimpleDocStream AnsiStyle -> Text
renderLazy (SimpleDocStream AnsiStyle -> Text)
-> (Doc AnsiStyle -> SimpleDocStream AnsiStyle)
-> Doc AnsiStyle
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LayoutOptions -> Doc AnsiStyle -> SimpleDocStream AnsiStyle
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty LayoutOptions
defaultLayoutOptions

docToText :: Doc AnsiStyle -> Text.Text
docToText :: Doc AnsiStyle -> Text
docToText = Text -> Text
TextLazy.toStrict (Text -> Text) -> (Doc AnsiStyle -> Text) -> Doc AnsiStyle -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc AnsiStyle -> Text
docToLazyText

black :: Doc AnsiStyle -> Doc AnsiStyle
black :: Doc AnsiStyle -> Doc AnsiStyle
black = AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. ann -> Doc ann -> Doc ann
annotate (Color -> AnsiStyle
color Color
Black)

red :: Doc AnsiStyle -> Doc AnsiStyle
red :: Doc AnsiStyle -> Doc AnsiStyle
red = AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. ann -> Doc ann -> Doc ann
annotate (Color -> AnsiStyle
color Color
Red)

green :: Doc AnsiStyle -> Doc AnsiStyle
green :: Doc AnsiStyle -> Doc AnsiStyle
green = AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. ann -> Doc ann -> Doc ann
annotate (Color -> AnsiStyle
color Color
Green)

yellow :: Doc AnsiStyle -> Doc AnsiStyle
yellow :: Doc AnsiStyle -> Doc AnsiStyle
yellow = AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. ann -> Doc ann -> Doc ann
annotate (Color -> AnsiStyle
color Color
Yellow)

blue :: Doc AnsiStyle -> Doc AnsiStyle
blue :: Doc AnsiStyle -> Doc AnsiStyle
blue = AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. ann -> Doc ann -> Doc ann
annotate (Color -> AnsiStyle
color Color
Blue)

magenta :: Doc AnsiStyle -> Doc AnsiStyle
magenta :: Doc AnsiStyle -> Doc AnsiStyle
magenta = AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. ann -> Doc ann -> Doc ann
annotate (Color -> AnsiStyle
color Color
Magenta)

cyan :: Doc AnsiStyle -> Doc AnsiStyle
cyan :: Doc AnsiStyle -> Doc AnsiStyle
cyan = AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. ann -> Doc ann -> Doc ann
annotate (Color -> AnsiStyle
color Color
Cyan)

white :: Doc AnsiStyle -> Doc AnsiStyle
white :: Doc AnsiStyle -> Doc AnsiStyle
white = AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. ann -> Doc ann -> Doc ann
annotate (Color -> AnsiStyle
color Color
White)

-- | Short hand for 'viaShow'.
pshow :: Show a => a -> Doc ann
pshow :: forall a ann. Show a => a -> Doc ann
pshow = a -> Doc ann
forall a ann. Show a => a -> Doc ann
viaShow

-- | Short hand for @'pretty' . 'displayException'@
prettyException :: Exception a => a -> Doc ann
prettyException :: forall a ann. Exception a => a -> Doc ann
prettyException = String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> (a -> String) -> a -> Doc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall e. Exception e => e -> String
displayException

renderBuildable :: Buildable a => a -> Text
renderBuildable :: forall a. Buildable a => a -> Text
renderBuildable a
e = Text -> Text
TextLazy.toStrict (Text -> Text) -> (Builder -> Text) -> Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
LText.toLazyText (Builder -> Text) -> Builder -> Text
forall a b. (a -> b) -> a -> b
$ a -> Builder
forall p. Buildable p => p -> Builder
Build.build a
e

textShow :: Show a => a -> Text
textShow :: forall a. Show a => a -> Text
textShow = String -> Text
Text.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show

instance Pretty L.Url where
  pretty :: forall ann. Url -> Doc ann
pretty Url
url = Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Url -> Text
L.urlToText Url
url)