content: {-# language OverloadedStrings #-}
  {-# language RecordWildCards #-}
  {-# language NamedFieldPuns #-}
  {-# language DeriveGeneric #-}
  module Main where
  
  import Data.Text (Text)
  import Data.Text.Lazy.IO as TIO
  import Text.RSS.Syntax
  import Text.Feed.Types (Feed(RSSFeed))
  import Text.Feed.Export (textFeed)
  
  import qualified Data.Aeson as Json
  import Data.Aeson (FromJSON)
  import GHC.Generics (Generic)
  import qualified Data.ByteString.Lazy as BS
  
  -- | Info from the config file
  data Config = Config
    { channelName :: Text
    , channelURL :: Text
    }
    deriving (Show, Generic)
  instance FromJSON Config where
  
  data Channel = Channel
    { channelInfo :: ChannelInfo
    , channelItems :: [ItemInfo]
    }
    deriving (Show, Generic)
  instance FromJSON Channel where
  
  -- | Info fetched from the channel
  data ChannelInfo = ChannelInfo
  
    { channelDescription :: Text
    , channelLastUpdate :: DateString -- TODO
    , channelImage :: Maybe () --RSSImage
    }
    deriving (Show, Generic)
  instance FromJSON ChannelInfo where
  
  -- | Info of each channel item
  data ItemInfo = ItemInfo
    { itemTitle :: Text
    , itemDescription :: Text
    , itemYoutubeLink :: Text
    , itemCategory :: Text
    , itemTags :: [Text]
    , itemURL :: Text
    , itemSizeBytes :: Integer
    , itemHash :: Text
    }
    deriving (Show, Generic)
  instance FromJSON ItemInfo where
  
  -- main = print $ textFeed $ RSSFeed $ toRSS
  --   (ChannelInfo
  --     { channelDescription = "description"
  --     , channelLastUpdate = "some date"
  --     , channelImage = nullImage "imageURL" "imageTitle" "imageLink"
  --     })
  --   []
  main :: IO ()
  main = do
    input <- BS.getContents
    let (Right rss) = Json.eitherDecode input
    let exConfig = (Config
          { channelName = "channel name"
          , channelURL = "channel url"
          })
    let (Just feed) = textFeed $ RSSFeed $ toRSS exConfig rss
    TIO.putStr feed
  
  toRSS :: Config -> Channel -> RSS
  toRSS Config{..} Channel{channelInfo, channelItems}  =
    let ChannelInfo{..} = channelInfo in
    (nullRSS channelName channelURL)
    { rssChannel = (nullChannel channelName channelURL)
        { rssDescription = channelDescription
        , rssLastUpdate = Just channelLastUpdate
        , rssImage = Nothing --channelImage TODO
        , rssGenerator = Just "youtube2audiopodcast"
        , rssItems = map rssItem channelItems
        }
    }
  
    where
      rssItem ItemInfo{..} = (nullItem itemTitle)
        { rssItemLink = Just itemYoutubeLink
        , rssItemDescription = Just itemDescription
        -- rssItemAuthor =
        , rssItemCategories =
          map (\name -> RSSCategory
                { rssCategoryDomain = Nothing
                , rssCategoryAttrs = []
                , rssCategoryValue = name
                }) $ itemCategory : itemTags
        , rssItemEnclosure = Just $ RSSEnclosure
            { rssEnclosureURL = itemURL
            , rssEnclosureLength = Just itemSizeBytes
            , rssEnclosureType = "audio/opus"
            , rssEnclosureAttrs = []
            }
        , rssItemGuid = Just $ RSSGuid
            { rssGuidPermanentURL = Just False
            , rssGuidAttrs = []
            , rssGuidValue = itemHash
            }
        -- TODO: date conversion
        -- https://tools.ietf.org/html/rfc822#section-5.1
        -- , rssItemPubDate 
        }
  