content: module Aws.Ec2.InstanceMetadata where
  
  import           Control.Applicative
  import           Control.Exception
  import           Control.Monad.Trans.Resource (throwM)
  import qualified Data.ByteString.Lazy as L
  import qualified Data.ByteString.Lazy.Char8 as B8
  import           Data.ByteString.Lazy.UTF8 as BU
  import           Data.Typeable
  import qualified Network.HTTP.Conduit as HTTP
  import           Prelude
  
  data InstanceMetadataException
    = MetadataNotFound String
    deriving (Show, Typeable)
  
  instance Exception InstanceMetadataException
  
  getInstanceMetadata :: HTTP.Manager -> String -> String -> IO L.ByteString
  getInstanceMetadata mgr p x = do
      req <- HTTP.parseUrlThrow ("http://169.254.169.254/" ++ p ++ '/' : x)
      HTTP.responseBody <$> HTTP.httpLbs req mgr
  
  getInstanceMetadataListing :: HTTP.Manager -> String -> IO [String]
  getInstanceMetadataListing mgr p = map BU.toString . B8.split '\n' <$> getInstanceMetadata mgr p ""
  
  getInstanceMetadataFirst :: HTTP.Manager -> String -> IO L.ByteString
  getInstanceMetadataFirst mgr p = do listing <- getInstanceMetadataListing mgr p
                                      case listing of
                                        [] -> throwM (MetadataNotFound p)
                                        (x:_) -> getInstanceMetadata mgr p x
  
  getInstanceMetadataOrFirst :: HTTP.Manager -> String -> Maybe String -> IO L.ByteString
  getInstanceMetadataOrFirst mgr p (Just x) = getInstanceMetadata mgr p x
  getInstanceMetadataOrFirst mgr p Nothing = getInstanceMetadataFirst mgr p
  