-- SPDX-FileCopyrightText: 2022 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA

-- | Module containing pretty-printing of Indigo contracts

module Indigo.Print
  ( printIndigoContract
  , renderIndigoDoc

  , printAsMichelson
  , saveAsMichelson
  , printDocumentation
  , saveDocumentation
  ) where

import Data.Text.Lazy.IO.Utf8 (writeFile)

import Indigo.Common.Object
import Indigo.Compilation
import Indigo.Frontend.Program (IndigoContract)
import Indigo.Lorentz
import Indigo.Prelude

-- | Pretty-print an Indigo contract into Michelson code.
printIndigoContract
  :: forall param st .
     ( IsObject st
     , NiceParameterFull param
     , NiceStorageFull st
     )
  => Bool -- ^ Force result to be single line
  -> CommentSettings
  -> IndigoContract param st
  -> LText
printIndigoContract :: forall param st.
(IsObject st, NiceParameterFull param, NiceStorageFull st) =>
Bool -> CommentSettings -> IndigoContract param st -> LText
printIndigoContract Bool
forceSingleLine CommentSettings
sett IndigoContract param st
ctr = Bool -> Contract param st () -> LText
forall cp st vd. Bool -> Contract cp st vd -> LText
printLorentzContract Bool
forceSingleLine (Contract param st () -> LText) -> Contract param st () -> LText
forall a b. (a -> b) -> a -> b
$
  ContractCode param st -> Contract param st ()
forall cp st.
(NiceParameterFull cp, NiceStorageFull st) =>
ContractCode cp st -> Contract cp st ()
mkContract (ContractCode param st -> Contract param st ())
-> ContractCode param st -> Contract param st ()
forall a b. (a -> b) -> a -> b
$
  forall param st.
(KnownValue param, IsObject st) =>
CommentSettings -> IndigoContract param st -> ContractCode param st
compileIndigoContractFull @param @st CommentSettings
sett IndigoContract param st
ctr

-- | Generate an Indigo contract documentation.
renderIndigoDoc
  :: forall param st .
     ( IsObject st
     , NiceParameterFull param
     , NiceStorageFull st
     )
  => IndigoContract param st
  -> LText
renderIndigoDoc :: forall param st.
(IsObject st, NiceParameterFull param, NiceStorageFull st) =>
IndigoContract param st -> LText
renderIndigoDoc IndigoContract param st
ctr =
  WithFinalizedDoc (Contract param st ()) -> LText
forall a. ContainsDoc a => WithFinalizedDoc a -> LText
buildMarkdownDoc (WithFinalizedDoc (Contract param st ()) -> LText)
-> (ContractCode param st
    -> WithFinalizedDoc (Contract param st ()))
-> ContractCode param st
-> LText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DGitRevision
-> Contract param st () -> WithFinalizedDoc (Contract param st ())
forall a.
ContainsUpdateableDoc a =>
DGitRevision -> a -> WithFinalizedDoc a
attachDocCommons DGitRevision
DGitRevisionUnknown (Contract param st () -> WithFinalizedDoc (Contract param st ()))
-> (ContractCode param st -> Contract param st ())
-> ContractCode param st
-> WithFinalizedDoc (Contract param st ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContractCode param st -> Contract param st ()
forall cp st.
(NiceParameterFull cp, NiceStorageFull st) =>
ContractCode cp st -> Contract cp st ()
mkContract (ContractCode param st -> LText) -> ContractCode param st -> LText
forall a b. (a -> b) -> a -> b
$
    forall param st.
(KnownValue param, IsObject st) =>
IndigoContract param st -> ContractCode param st
compileIndigoContract @param @st IndigoContract param st
ctr

-- | Prints the pretty-printed Michelson code of an Indigo contract to
-- the standard output.
--
-- This is intended to be easy to use for newcomers.
printAsMichelson
  :: forall param st m . ( IsObject st
     , NiceParameterFull param, NiceStorageFull st
     , MonadIO m
     )
  => CommentSettings
  -> IndigoContract param st
  -> m ()
printAsMichelson :: forall param st (m :: * -> *).
(IsObject st, NiceParameterFull param, NiceStorageFull st,
 MonadIO m) =>
CommentSettings -> IndigoContract param st -> m ()
printAsMichelson CommentSettings
sett IndigoContract param st
cntr = LText -> m ()
forall a (m :: * -> *). (Print a, MonadIO m) => a -> m ()
putStrLn (forall param st.
(IsObject st, NiceParameterFull param, NiceStorageFull st) =>
Bool -> CommentSettings -> IndigoContract param st -> LText
printIndigoContract @param @st Bool
False CommentSettings
sett IndigoContract param st
cntr)

-- | Saves the pretty-printed Michelson code of an Indigo contract to
-- the given file.
--
-- This is intended to be easy to use for newcomers.
saveAsMichelson
  :: forall param st m . ( IsObject st
     , NiceParameterFull param, NiceStorageFull st
     , MonadIO m, MonadMask m
     )
  => CommentSettings
  -> IndigoContract param st
  -> FilePath
  -> m ()
saveAsMichelson :: forall param st (m :: * -> *).
(IsObject st, NiceParameterFull param, NiceStorageFull st,
 MonadIO m, MonadMask m) =>
CommentSettings -> IndigoContract param st -> FilePath -> m ()
saveAsMichelson CommentSettings
sett IndigoContract param st
cntr FilePath
filePath =
  FilePath -> LText -> m ()
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
FilePath -> LText -> m ()
writeFile FilePath
filePath (forall param st.
(IsObject st, NiceParameterFull param, NiceStorageFull st) =>
Bool -> CommentSettings -> IndigoContract param st -> LText
printIndigoContract @param @st Bool
False CommentSettings
sett IndigoContract param st
cntr)

-- | Print the generated documentation to the standard output.
printDocumentation
  :: forall param st m .
     ( IsObject st
     , NiceParameterFull param
     , NiceStorageFull st
     , MonadIO m
     )
  => IndigoContract param st
  -> m ()
printDocumentation :: forall param st (m :: * -> *).
(IsObject st, NiceParameterFull param, NiceStorageFull st,
 MonadIO m) =>
IndigoContract param st -> m ()
printDocumentation IndigoContract param st
ctr =
  LText -> m ()
forall a (m :: * -> *). (Print a, MonadIO m) => a -> m ()
putStrLn (LText -> m ()) -> LText -> m ()
forall a b. (a -> b) -> a -> b
$ forall param st.
(IsObject st, NiceParameterFull param, NiceStorageFull st) =>
IndigoContract param st -> LText
renderIndigoDoc @param @st IndigoContract param st
ctr

-- | Save the generated documentation to the given file.
saveDocumentation
  :: forall param st m .
     ( IsObject st
     , NiceParameterFull param
     , NiceStorageFull st
     , MonadIO m, MonadMask m
     )
  => IndigoContract param st
  -> FilePath
  -> m ()
saveDocumentation :: forall param st (m :: * -> *).
(IsObject st, NiceParameterFull param, NiceStorageFull st,
 MonadIO m, MonadMask m) =>
IndigoContract param st -> FilePath -> m ()
saveDocumentation IndigoContract param st
ctr FilePath
filePath = do
  FilePath -> LText -> m ()
forall (m :: * -> *).
(MonadIO m, MonadMask m) =>
FilePath -> LText -> m ()
writeFile FilePath
filePath (forall param st.
(IsObject st, NiceParameterFull param, NiceStorageFull st) =>
IndigoContract param st -> LText
renderIndigoDoc @param @st IndigoContract param st
ctr)