-----------------------------------------------------------------------------
-- |
-- Module      :  Network.AWS.AWSConnection
-- Copyright   :  (c) Greg Heartsfield 2007
-- License     :  BSD3
--
-- Connection and authentication info for an Amazon AWS request.
-----------------------------------------------------------------------------
module Network.AWS.AWSConnection (
   -- * Constants
   defaultAmazonSimpleDBHost, defaultAmazonSimpleDBPort,
   -- * Function Types
   amazonSimpleDBConnection, amazonConnectionFromEnv, amazonConnectionFromEnv',
   -- * Data Types
   AWSConnection(..)
   ) where

import System.Environment

-- | An Amazon Web Services connection.  Everything needed to connect
--   and authenticate requests.
data AWSConnection =
    AWSConnection { awsHost :: String, -- ^ Service provider hostname
                    awsPort :: Int,    -- ^ Service provider port number
                    awsAccessKey :: String, -- ^ Access Key ID
                    awsSecretKey :: String  -- ^ Secret Access Key
                  } deriving (Show)

-- | Hostname used for connecting to Amazon's production S3 service (@s3.amazonaws.com@).
defaultAmazonS3Host :: String
defaultAmazonS3Host = "s3.amazonaws.com"

-- | Hostname used for connecting to Amazon's production SimpleDB service (@sdb.amazonaws.com@).
defaultAmazonSimpleDBHost :: String
defaultAmazonSimpleDBHost = "sdb.amazonaws.com"

-- | Port number used for connecting to Amazon's production S3 service (@80@).
defaultAmazonS3Port :: Int
defaultAmazonS3Port = 80

-- | Port number used for connecting to Amazon's production SimpleDB service (@80@).
defaultAmazonSimpleDBPort :: Int
defaultAmazonSimpleDBPort = 80

-- | Create an AWSConnection to Amazon from credentials.  Uses the
--   production service.
amazonSimpleDBConnection :: String -- ^ Access Key ID
                         -> String -- ^ Secret Access Key
                         -> AWSConnection -- ^ Connection to Amazon S3
amazonSimpleDBConnection = AWSConnection defaultAmazonSimpleDBHost defaultAmazonSimpleDBPort

-- | Retrieve Access and Secret keys from environment variables
--   AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, respectively.
--   Either variable being undefined or empty will result in
--   'Nothing'.
amazonConnectionFromEnv :: IO (Maybe AWSConnection)
amazonConnectionFromEnv =
    do ak <- getEnvKey "AWS_ACCESS_KEY_ID"
       sk0 <- getEnvKey "AWS_ACCESS_KEY_SECRET"
       sk1 <- getEnvKey "AWS_SECRET_ACCESS_KEY"
       return $ case (ak, sk0, sk1) of
                  ("",  _,  _) -> Nothing
                  ( _, "", "") -> Nothing
                  ( _, "",  _) -> Just (amazonSimpleDBConnection ak sk1)
                  ( _,  _,  _) -> Just (amazonSimpleDBConnection ak sk0)
    where getEnvKey s = catch (getEnv s) (const $ return "")

-- | Retrieve Access and Secret keys from environment variables
--   AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, respectively.
--   Either variable being undefined or empty will result in
--   an exception.
amazonConnectionFromEnv' :: IO AWSConnection
amazonConnectionFromEnv' =
    do mbConn <- amazonConnectionFromEnv
       case mbConn of
         Nothing   -> error "Please define the AWS_ACCESS_KEY_ID and AWS_ACCESS_KEY_SECRET environment variables."
         Just conn -> return conn

