content: {-# LANGUAGE DeriveGeneric     #-}
  {-# LANGUAGE OverloadedStrings #-}
  
  module Program where
  
  import           Data.Aeson
  import           Data.Aeson.Encode.Pretty
  import qualified Data.ByteString.Lazy     as B
  import qualified Data.Text                as T
  import           GHC.Generics
  import           System.Directory
  
  instance FromJSON File where
    parseJSON (Object v) = File
      <$> v .: "path"
      <*> v .: "movable"
      <*> v .: "help"
  
  data Program = Program
    { name  :: T.Text,
      files :: [File]
    }
    deriving (Generic, Show)
  
  instance ToJSON Program where
    toJSON (Program name files) = object [ "name" .= name, "files" .= files ]
    toEncoding (Program name files) = pairs ("name" .= name <> "files" .= files)
  instance FromJSON Program
  
  data File = File
    { path         :: String,
      supportLevel :: SupportLevel,
      help         :: String
    }
    deriving (Generic, Show)
  
  instance ToJSON File where
    toJSON (File path supportLevel help) = object [ "path" .= path, "movable" .= supportLevel, "help" .= help ]
    toEncoding (File path supportLevel help) = pairs ("path" .= path <> "movable" .= supportLevel <> "help" .= help)
  
  data SupportLevel = Unsupported | Alias | EnvVars | Supported
    deriving (Generic, Show)
  
  instance ToJSON SupportLevel where
    toJSON Unsupported = toJSON (Bool False)
    toJSON _           = toJSON (Bool True)
    toEncoding Unsupported = toEncoding ( Bool False )
    toEncoding _           = toEncoding ( Bool True )
  instance FromJSON SupportLevel where
    parseJSON (Bool False) = return Unsupported
    parseJSON (Bool True)  = return EnvVars
  
  makeFilename :: T.Text -> T.Text
  makeFilename s = T.pack ( "./programs/" ++ T.unpack s ++ ".json" )
  
  save :: T.Text -> Program -> IO ()
  save filename program = do
    createDirectoryIfMissing False "./programs/"
    B.writeFile (T.unpack filename) (encodePretty program)
  
  readProgram :: String -> IO ( Maybe Program )
  readProgram filename = do
      json_data <- B.readFile filename
      return (decode json_data)
  