content: module Main (main) where
  
  import Control.Exception (Exception (..), SomeException)
  import Control.Monad (void)
  import Data.Version (showVersion)
  import Data.Yaml (decodeFileThrow, prettyPrintParseException)
  import qualified GI.GLib as GLib
  import qualified GI.Gtk as Gtk
  import Model.Indicator (newIndicator)
  import Model.Item (populate)
  import Model.Root (Root (..))
  import Options (Options (..), Settings (..), parseArgs)
  import Paths_systranything (version)
  import System.Environment (getProgName)
  import System.Exit (exitFailure)
  import System.IO (hPutStr, stderr)
  import UnliftIO (handleAny)
  
  main :: IO ()
  main = do
    options <- parseArgs
    case options of
      OpVersion -> do
        progName <- getProgName
        putStrLn $ progName <> " " <> showVersion version
      OpOptions (MkSettings {..}) ->
        handleAny exceptions $ do
          MkRoot {..} <- decodeFileThrow seFilename
  
          void . Gtk.init $ Nothing
  
          mbMenu <- traverse (populate seVerbose) roMenu
          indicator <- newIndicator seVerbose roIndicator mbMenu
  
          -- Make sure the indicator is not garbage collected. That's mandatory
          -- for the case when there is no periodic update to keep the indicator
          -- alive.
          Gtk.withManagedPtr indicator . const $
            GLib.mainLoopRun =<< GLib.mainLoopNew Nothing False
  
  exceptions :: SomeException -> IO ()
  exceptions e = hPutStr stderr message >> exitFailure
    where
      message
        | Just parseException <- fromException e =
            prettyPrintParseException parseException <> "\n"
        | otherwise = "Unknown exception: " <> show e
  