{-# LANGUAGE DataKinds                   #-}
{-# LANGUAGE DeriveGeneric               #-}
{-# LANGUAGE FlexibleInstances           #-}
{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
{-# LANGUAGE LambdaCase                  #-}
{-# LANGUAGE NoImplicitPrelude           #-}
{-# LANGUAGE OverloadedStrings           #-}
{-# LANGUAGE RecordWildCards             #-}
{-# LANGUAGE TypeFamilies                #-}

{-# OPTIONS_GHC -fno-warn-unused-imports #-}

-- Module      : Network.AWS.ElastiCache.CreateCacheCluster
-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
-- License     : This Source Code Form is subject to the terms of
--               the Mozilla Public License, v. 2.0.
--               A copy of the MPL can be found in the LICENSE file or
--               you can obtain it at http://mozilla.org/MPL/2.0/.
-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--
-- Derived from AWS service descriptions, licensed under Apache 2.0.

-- | The /CreateCacheCluster/ operation creates a cache cluster. All nodes in the
-- cache cluster run the same protocol-compliant cache engine software, either
-- Memcached or Redis.
--
-- <http://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateCacheCluster.html>
module Network.AWS.ElastiCache.CreateCacheCluster
    (
    -- * Request
      CreateCacheCluster
    -- ** Request constructor
    , createCacheCluster
    -- ** Request lenses
    , cccAZMode
    , cccAutoMinorVersionUpgrade
    , cccCacheClusterId
    , cccCacheNodeType
    , cccCacheParameterGroupName
    , cccCacheSecurityGroupNames
    , cccCacheSubnetGroupName
    , cccEngine
    , cccEngineVersion
    , cccNotificationTopicArn
    , cccNumCacheNodes
    , cccPort
    , cccPreferredAvailabilityZone
    , cccPreferredAvailabilityZones
    , cccPreferredMaintenanceWindow
    , cccReplicationGroupId
    , cccSecurityGroupIds
    , cccSnapshotArns
    , cccSnapshotName
    , cccSnapshotRetentionLimit
    , cccSnapshotWindow

    -- * Response
    , CreateCacheClusterResponse
    -- ** Response constructor
    , createCacheClusterResponse
    -- ** Response lenses
    , cccrCacheCluster
    ) where

import Network.AWS.Prelude
import Network.AWS.Request.Query
import Network.AWS.ElastiCache.Types
import qualified GHC.Exts

data CreateCacheCluster = CreateCacheCluster
    { _cccAZMode                     :: Maybe AZMode
    , _cccAutoMinorVersionUpgrade    :: Maybe Bool
    , _cccCacheClusterId             :: Text
    , _cccCacheNodeType              :: Maybe Text
    , _cccCacheParameterGroupName    :: Maybe Text
    , _cccCacheSecurityGroupNames    :: List "member" Text
    , _cccCacheSubnetGroupName       :: Maybe Text
    , _cccEngine                     :: Maybe Text
    , _cccEngineVersion              :: Maybe Text
    , _cccNotificationTopicArn       :: Maybe Text
    , _cccNumCacheNodes              :: Maybe Int
    , _cccPort                       :: Maybe Int
    , _cccPreferredAvailabilityZone  :: Maybe Text
    , _cccPreferredAvailabilityZones :: List "member" Text
    , _cccPreferredMaintenanceWindow :: Maybe Text
    , _cccReplicationGroupId         :: Maybe Text
    , _cccSecurityGroupIds           :: List "member" Text
    , _cccSnapshotArns               :: List "member" Text
    , _cccSnapshotName               :: Maybe Text
    , _cccSnapshotRetentionLimit     :: Maybe Int
    , _cccSnapshotWindow             :: Maybe Text
    } deriving (Eq, Show)

-- | 'CreateCacheCluster' constructor.
--
-- The fields accessible through corresponding lenses are:
--
-- * 'cccAZMode' @::@ 'Maybe' 'AZMode'
--
-- * 'cccAutoMinorVersionUpgrade' @::@ 'Maybe' 'Bool'
--
-- * 'cccCacheClusterId' @::@ 'Text'
--
-- * 'cccCacheNodeType' @::@ 'Maybe' 'Text'
--
-- * 'cccCacheParameterGroupName' @::@ 'Maybe' 'Text'
--
-- * 'cccCacheSecurityGroupNames' @::@ ['Text']
--
-- * 'cccCacheSubnetGroupName' @::@ 'Maybe' 'Text'
--
-- * 'cccEngine' @::@ 'Maybe' 'Text'
--
-- * 'cccEngineVersion' @::@ 'Maybe' 'Text'
--
-- * 'cccNotificationTopicArn' @::@ 'Maybe' 'Text'
--
-- * 'cccNumCacheNodes' @::@ 'Maybe' 'Int'
--
-- * 'cccPort' @::@ 'Maybe' 'Int'
--
-- * 'cccPreferredAvailabilityZone' @::@ 'Maybe' 'Text'
--
-- * 'cccPreferredAvailabilityZones' @::@ ['Text']
--
-- * 'cccPreferredMaintenanceWindow' @::@ 'Maybe' 'Text'
--
-- * 'cccReplicationGroupId' @::@ 'Maybe' 'Text'
--
-- * 'cccSecurityGroupIds' @::@ ['Text']
--
-- * 'cccSnapshotArns' @::@ ['Text']
--
-- * 'cccSnapshotName' @::@ 'Maybe' 'Text'
--
-- * 'cccSnapshotRetentionLimit' @::@ 'Maybe' 'Int'
--
-- * 'cccSnapshotWindow' @::@ 'Maybe' 'Text'
--
createCacheCluster :: Text -- ^ 'cccCacheClusterId'
                   -> CreateCacheCluster
createCacheCluster p1 = CreateCacheCluster
    { _cccCacheClusterId             = p1
    , _cccReplicationGroupId         = Nothing
    , _cccAZMode                     = Nothing
    , _cccPreferredAvailabilityZone  = Nothing
    , _cccPreferredAvailabilityZones = mempty
    , _cccNumCacheNodes              = Nothing
    , _cccCacheNodeType              = Nothing
    , _cccEngine                     = Nothing
    , _cccEngineVersion              = Nothing
    , _cccCacheParameterGroupName    = Nothing
    , _cccCacheSubnetGroupName       = Nothing
    , _cccCacheSecurityGroupNames    = mempty
    , _cccSecurityGroupIds           = mempty
    , _cccSnapshotArns               = mempty
    , _cccSnapshotName               = Nothing
    , _cccPreferredMaintenanceWindow = Nothing
    , _cccPort                       = Nothing
    , _cccNotificationTopicArn       = Nothing
    , _cccAutoMinorVersionUpgrade    = Nothing
    , _cccSnapshotRetentionLimit     = Nothing
    , _cccSnapshotWindow             = Nothing
    }

-- | Specifies whether the nodes in this Memcached node group are created in a
-- single Availability Zone or created across multiple Availability Zones in the
-- cluster's region.
--
-- This parameter is only supported for Memcached cache clusters.
--
-- If the 'AZMode' and 'PreferredAvailabilityZones' are not specified, ElastiCache
-- assumes 'single-az' mode.
cccAZMode :: Lens' CreateCacheCluster (Maybe AZMode)
cccAZMode = lens _cccAZMode (\s a -> s { _cccAZMode = a })

-- | Determines whether minor engine upgrades will be applied automatically to the
-- node group during the maintenance window. A value of 'true' allows these
-- upgrades to occur; 'false' disables automatic upgrades.
--
-- Default: 'true'
cccAutoMinorVersionUpgrade :: Lens' CreateCacheCluster (Maybe Bool)
cccAutoMinorVersionUpgrade =
    lens _cccAutoMinorVersionUpgrade
        (\s a -> s { _cccAutoMinorVersionUpgrade = a })

-- | The node group identifier. This parameter is stored as a lowercase string.
--
-- Constraints:
--
-- A name must contain from 1 to 20 alphanumeric characters or hyphens. The
-- first character must be a letter. A name cannot end with a hyphen or contain
-- two consecutive hyphens.
cccCacheClusterId :: Lens' CreateCacheCluster Text
cccCacheClusterId =
    lens _cccCacheClusterId (\s a -> s { _cccCacheClusterId = a })

-- | The compute and memory capacity of the nodes in the node group.
--
-- Valid node types are as follows:
--
-- General purpose:  Current generation: 'cache.t2.micro', 'cache.t2.small', 'cache.t2.medium', 'cache.m3.medium', 'cache.m3.large', 'cache.m3.xlarge', 'cache.m3.2xlarge' Previous
-- generation: 'cache.t1.micro', 'cache.m1.small', 'cache.m1.medium', 'cache.m1.large', 'cache.m1.xlarge'  Compute optimized: 'cache.c1.xlarge' Memory optimized  Current generation: 'cache.r3.large', 'cache.r3.xlarge', 'cache.r3.2xlarge', 'cache.r3.4xlarge', 'cache.r3.8xlarge' Previous generation:
-- 'cache.m2.xlarge', 'cache.m2.2xlarge', 'cache.m2.4xlarge'   Notes:
--
-- All t2 instances are created in an Amazon Virtual Private Cloud (VPC). Redis backup/restore is not supported for t2 instances.
-- Redis Append-only files (AOF) functionality is not supported for t1 or t2
-- instances.  For a complete listing of cache node types and specifications,
-- see <http://aws.amazon.com/elasticache/details Amazon ElastiCache Product Features and Details> and <http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/CacheParameterGroups.Memcached.html#CacheParameterGroups.Memcached.NodeSpecific Cache NodeType-Specific Parameters for Memcached> or <http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/CacheParameterGroups.Redis.html#CacheParameterGroups.Redis.NodeSpecific Cache Node Type-Specific Parametersfor Redis>.
cccCacheNodeType :: Lens' CreateCacheCluster (Maybe Text)
cccCacheNodeType = lens _cccCacheNodeType (\s a -> s { _cccCacheNodeType = a })

-- | The name of the parameter group to associate with this cache cluster. If this
-- argument is omitted, the default parameter group for the specified engine is
-- used.
cccCacheParameterGroupName :: Lens' CreateCacheCluster (Maybe Text)
cccCacheParameterGroupName =
    lens _cccCacheParameterGroupName
        (\s a -> s { _cccCacheParameterGroupName = a })

-- | A list of security group names to associate with this cache cluster.
--
-- Use this parameter only when you are creating a cache cluster outside of an
-- Amazon Virtual Private Cloud (VPC).
cccCacheSecurityGroupNames :: Lens' CreateCacheCluster [Text]
cccCacheSecurityGroupNames =
    lens _cccCacheSecurityGroupNames
        (\s a -> s { _cccCacheSecurityGroupNames = a })
            . _List

-- | The name of the subnet group to be used for the cache cluster.
--
-- Use this parameter only when you are creating a cache cluster in an Amazon
-- Virtual Private Cloud (VPC).
cccCacheSubnetGroupName :: Lens' CreateCacheCluster (Maybe Text)
cccCacheSubnetGroupName =
    lens _cccCacheSubnetGroupName (\s a -> s { _cccCacheSubnetGroupName = a })

-- | The name of the cache engine to be used for this cache cluster.
--
-- Valid values for this parameter are:
--
-- 'memcached' | 'redis'
cccEngine :: Lens' CreateCacheCluster (Maybe Text)
cccEngine = lens _cccEngine (\s a -> s { _cccEngine = a })

-- | The version number of the cache engine to be used for this cache cluster. To
-- view the supported cache engine versions, use the /DescribeCacheEngineVersions/
-- operation.
cccEngineVersion :: Lens' CreateCacheCluster (Maybe Text)
cccEngineVersion = lens _cccEngineVersion (\s a -> s { _cccEngineVersion = a })

-- | The Amazon Resource Name (ARN) of the Amazon Simple Notification Service
-- (SNS) topic to which notifications will be sent.
cccNotificationTopicArn :: Lens' CreateCacheCluster (Maybe Text)
cccNotificationTopicArn =
    lens _cccNotificationTopicArn (\s a -> s { _cccNotificationTopicArn = a })

-- | The initial number of cache nodes that the cache cluster will have.
--
-- For Memcached, valid values are between 1 and 20. If you need to exceed this
-- limit, please fill out the ElastiCache Limit Increase Request form at <http://aws.amazon.com/contact-us/elasticache-node-limit-request/ http://aws.amazon.com/contact-us/elasticache-node-limit-request/>.
--
-- For Redis, only single-node cache cluster are supported at this time, so the
-- value for this parameter must be 1.
cccNumCacheNodes :: Lens' CreateCacheCluster (Maybe Int)
cccNumCacheNodes = lens _cccNumCacheNodes (\s a -> s { _cccNumCacheNodes = a })

-- | The port number on which each of the cache nodes will accept connections.
cccPort :: Lens' CreateCacheCluster (Maybe Int)
cccPort = lens _cccPort (\s a -> s { _cccPort = a })

-- | The EC2 Availability Zone in which the cache cluster will be created.
--
-- All nodes belonging to this Memcached cache cluster are placed in the
-- preferred Availability Zone. If you want to create your nodes across multiple
-- Availability Zones, use 'PreferredAvailabilityZones'.
--
-- Default: System chosen Availability Zone.
cccPreferredAvailabilityZone :: Lens' CreateCacheCluster (Maybe Text)
cccPreferredAvailabilityZone =
    lens _cccPreferredAvailabilityZone
        (\s a -> s { _cccPreferredAvailabilityZone = a })

-- | A list of the Availability Zones in which cache nodes will be created. The
-- order of the zones in the list is not important.
--
-- This option is only supported on Memcached.
--
-- If you want all the nodes in the same Availability Zone, use 'PreferredAvailabilityZone' instead, or repeat the Availability Zone multiple times in the list.
--
-- Default: System chosen Availability Zones.
--
-- Example: One Memcached node in each of three different Availability Zones: 'PreferredAvailabilityZones.member.1=us-east-1a&PreferredAvailabilityZones.member.2=us-east-1b&PreferredAvailabilityZones.member.3=us-east-1d'
--
-- Example: All three Memcached nodes in one Availability Zone: 'PreferredAvailabilityZones.member.1=us-east-1a&PreferredAvailabilityZones.member.2=us-east-1a&PreferredAvailabilityZones.member.3=us-east-1a'
cccPreferredAvailabilityZones :: Lens' CreateCacheCluster [Text]
cccPreferredAvailabilityZones =
    lens _cccPreferredAvailabilityZones
        (\s a -> s { _cccPreferredAvailabilityZones = a })
            . _List

-- | The weekly time range (in UTC) during which system maintenance can occur.
--
-- Example: 'sun:05:00-sun:09:00'
cccPreferredMaintenanceWindow :: Lens' CreateCacheCluster (Maybe Text)
cccPreferredMaintenanceWindow =
    lens _cccPreferredMaintenanceWindow
        (\s a -> s { _cccPreferredMaintenanceWindow = a })

-- | The ID of the replication group to which this cache cluster should belong. If
-- this parameter is specified, the cache cluster will be added to the specified
-- replication group as a read replica; otherwise, the cache cluster will be a
-- standalone primary that is not part of any replication group.
--
-- If the specified replication group is Automatic Failover enabled and the
-- availability zone is not specified, the cache cluster will be created in
-- availability zones that provide the best spread of read replicas across
-- availability zones.
--
-- Note: This parameter is only valid if the 'Engine' parameter is 'redis'.
cccReplicationGroupId :: Lens' CreateCacheCluster (Maybe Text)
cccReplicationGroupId =
    lens _cccReplicationGroupId (\s a -> s { _cccReplicationGroupId = a })

-- | One or more VPC security groups associated with the cache cluster.
--
-- Use this parameter only when you are creating a cache cluster in an Amazon
-- Virtual Private Cloud (VPC).
cccSecurityGroupIds :: Lens' CreateCacheCluster [Text]
cccSecurityGroupIds =
    lens _cccSecurityGroupIds (\s a -> s { _cccSecurityGroupIds = a })
        . _List

-- | A single-element string list containing an Amazon Resource Name (ARN) that
-- uniquely identifies a Redis RDB snapshot file stored in Amazon S3. The
-- snapshot file will be used to populate the node group. The Amazon S3 object
-- name in the ARN cannot contain any commas.
--
-- Note: This parameter is only valid if the 'Engine' parameter is 'redis'.
--
-- Example of an Amazon S3 ARN: 'arn:aws:s3:::my_bucket/snapshot1.rdb'
cccSnapshotArns :: Lens' CreateCacheCluster [Text]
cccSnapshotArns = lens _cccSnapshotArns (\s a -> s { _cccSnapshotArns = a }) . _List

-- | The name of a snapshot from which to restore data into the new node group.
-- The snapshot status changes to 'restoring' while the new node group is being
-- created.
--
-- Note: This parameter is only valid if the 'Engine' parameter is 'redis'.
cccSnapshotName :: Lens' CreateCacheCluster (Maybe Text)
cccSnapshotName = lens _cccSnapshotName (\s a -> s { _cccSnapshotName = a })

-- | The number of days for which ElastiCache will retain automatic snapshots
-- before deleting them. For example, if you set 'SnapshotRetentionLimit' to 5,
-- then a snapshot that was taken today will be retained for 5 days before being
-- deleted.
--
-- Note: This parameter is only valid if the 'Engine' parameter is 'redis'.
--
-- Default: 0 (i.e., automatic backups are disabled for this cache cluster).
cccSnapshotRetentionLimit :: Lens' CreateCacheCluster (Maybe Int)
cccSnapshotRetentionLimit =
    lens _cccSnapshotRetentionLimit
        (\s a -> s { _cccSnapshotRetentionLimit = a })

-- | The daily time range (in UTC) during which ElastiCache will begin taking a
-- daily snapshot of your node group.
--
-- Example: '05:00-09:00'
--
-- If you do not specify this parameter, then ElastiCache will automatically
-- choose an appropriate time range.
--
-- Note: This parameter is only valid if the 'Engine' parameter is 'redis'.
cccSnapshotWindow :: Lens' CreateCacheCluster (Maybe Text)
cccSnapshotWindow =
    lens _cccSnapshotWindow (\s a -> s { _cccSnapshotWindow = a })

newtype CreateCacheClusterResponse = CreateCacheClusterResponse
    { _cccrCacheCluster :: Maybe CacheCluster
    } deriving (Eq, Show)

-- | 'CreateCacheClusterResponse' constructor.
--
-- The fields accessible through corresponding lenses are:
--
-- * 'cccrCacheCluster' @::@ 'Maybe' 'CacheCluster'
--
createCacheClusterResponse :: CreateCacheClusterResponse
createCacheClusterResponse = CreateCacheClusterResponse
    { _cccrCacheCluster = Nothing
    }

cccrCacheCluster :: Lens' CreateCacheClusterResponse (Maybe CacheCluster)
cccrCacheCluster = lens _cccrCacheCluster (\s a -> s { _cccrCacheCluster = a })

instance ToPath CreateCacheCluster where
    toPath = const "/"

instance ToQuery CreateCacheCluster where
    toQuery CreateCacheCluster{..} = mconcat
        [ "AZMode"                     =? _cccAZMode
        , "AutoMinorVersionUpgrade"    =? _cccAutoMinorVersionUpgrade
        , "CacheClusterId"             =? _cccCacheClusterId
        , "CacheNodeType"              =? _cccCacheNodeType
        , "CacheParameterGroupName"    =? _cccCacheParameterGroupName
        , "CacheSecurityGroupNames"    =? _cccCacheSecurityGroupNames
        , "CacheSubnetGroupName"       =? _cccCacheSubnetGroupName
        , "Engine"                     =? _cccEngine
        , "EngineVersion"              =? _cccEngineVersion
        , "NotificationTopicArn"       =? _cccNotificationTopicArn
        , "NumCacheNodes"              =? _cccNumCacheNodes
        , "Port"                       =? _cccPort
        , "PreferredAvailabilityZone"  =? _cccPreferredAvailabilityZone
        , "PreferredAvailabilityZones" =? _cccPreferredAvailabilityZones
        , "PreferredMaintenanceWindow" =? _cccPreferredMaintenanceWindow
        , "ReplicationGroupId"         =? _cccReplicationGroupId
        , "SecurityGroupIds"           =? _cccSecurityGroupIds
        , "SnapshotArns"               =? _cccSnapshotArns
        , "SnapshotName"               =? _cccSnapshotName
        , "SnapshotRetentionLimit"     =? _cccSnapshotRetentionLimit
        , "SnapshotWindow"             =? _cccSnapshotWindow
        ]

instance ToHeaders CreateCacheCluster

instance AWSRequest CreateCacheCluster where
    type Sv CreateCacheCluster = ElastiCache
    type Rs CreateCacheCluster = CreateCacheClusterResponse

    request  = post "CreateCacheCluster"
    response = xmlResponse

instance FromXML CreateCacheClusterResponse where
    parseXML = withElement "CreateCacheClusterResult" $ \x -> CreateCacheClusterResponse
        <$> x .@? "CacheCluster"