{-# 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.Route53.CreateHostedZone
-- 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.

-- | This action creates a new hosted zone.
--
-- To create a new hosted zone, send a 'POST' request to the '2013-04-01/hostedzone'
-- resource. The request body must include an XML document with a 'CreateHostedZoneRequest' element. The response returns the 'CreateHostedZoneResponse' element that
-- contains metadata about the hosted zone.
--
-- Route 53 automatically creates a default SOA record and four NS records for
-- the zone. The NS records in the hosted zone are the name servers you give
-- your registrar to delegate your domain to. For more information about SOA and
-- NS records, see <http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/SOA-NSrecords.html NS and SOA Records that Route 53 Creates for a Hosted Zone> in
-- the /Amazon Route 53 Developer Guide/.
--
-- When you create a zone, its initial status is 'PENDING'. This means that it is
-- not yet available on all DNS servers. The status of the zone changes to 'INSYNC'
-- when the NS and SOA records are available on all Route 53 DNS servers.
--
-- When trying to create a hosted zone using a reusable delegation set, you
-- could specify an optional DelegationSetId, and Route53 would assign those 4
-- NS records for the zone, instead of alloting a new one.
--
-- <http://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateHostedZone.html>
module Network.AWS.Route53.CreateHostedZone
    (
    -- * Request
      CreateHostedZone
    -- ** Request constructor
    , createHostedZone
    -- ** Request lenses
    , chzCallerReference
    , chzDelegationSetId
    , chzHostedZoneConfig
    , chzName
    , chzVPC

    -- * Response
    , CreateHostedZoneResponse
    -- ** Response constructor
    , createHostedZoneResponse
    -- ** Response lenses
    , chzrChangeInfo
    , chzrDelegationSet
    , chzrHostedZone
    , chzrLocation
    , chzrVPC
    ) where

import Network.AWS.Prelude
import Network.AWS.Request.RestXML
import Network.AWS.Route53.Types
import qualified GHC.Exts

data CreateHostedZone = CreateHostedZone
    { _chzCallerReference  :: Text
    , _chzDelegationSetId  :: Maybe Text
    , _chzHostedZoneConfig :: Maybe HostedZoneConfig
    , _chzName             :: Text
    , _chzVPC              :: Maybe VPC
    } deriving (Eq, Read, Show)

-- | 'CreateHostedZone' constructor.
--
-- The fields accessible through corresponding lenses are:
--
-- * 'chzCallerReference' @::@ 'Text'
--
-- * 'chzDelegationSetId' @::@ 'Maybe' 'Text'
--
-- * 'chzHostedZoneConfig' @::@ 'Maybe' 'HostedZoneConfig'
--
-- * 'chzName' @::@ 'Text'
--
-- * 'chzVPC' @::@ 'Maybe' 'VPC'
--
createHostedZone :: Text -- ^ 'chzName'
                 -> Text -- ^ 'chzCallerReference'
                 -> CreateHostedZone
createHostedZone p1 p2 = CreateHostedZone
    { _chzName             = p1
    , _chzCallerReference  = p2
    , _chzVPC              = Nothing
    , _chzHostedZoneConfig = Nothing
    , _chzDelegationSetId  = Nothing
    }

-- | A unique string that identifies the request and that allows failed 'CreateHostedZone' requests to be retried without the risk of executing the operation twice.
-- You must use a unique 'CallerReference' string every time you create a hosted
-- zone. 'CallerReference' can be any unique string; you might choose to use a
-- string that identifies your project, such as 'DNSMigration_01'.
--
-- Valid characters are any Unicode code points that are legal in an XML 1.0
-- document. The UTF-8 encoding of the value must be less than 128 bytes.
chzCallerReference :: Lens' CreateHostedZone Text
chzCallerReference =
    lens _chzCallerReference (\s a -> s { _chzCallerReference = a })

-- | The delegation set id of the reusable delgation set whose NS records you want
-- to assign to the new hosted zone.
chzDelegationSetId :: Lens' CreateHostedZone (Maybe Text)
chzDelegationSetId =
    lens _chzDelegationSetId (\s a -> s { _chzDelegationSetId = a })

-- | A complex type that contains an optional comment about your hosted zone.
chzHostedZoneConfig :: Lens' CreateHostedZone (Maybe HostedZoneConfig)
chzHostedZoneConfig =
    lens _chzHostedZoneConfig (\s a -> s { _chzHostedZoneConfig = a })

-- | The name of the domain. This must be a fully-specified domain, for example,
-- www.example.com. The trailing dot is optional; Route 53 assumes that the
-- domain name is fully qualified. This means that Route 53 treats
-- www.example.com (without a trailing dot) and www.example.com. (with a
-- trailing dot) as identical.
--
-- This is the name you have registered with your DNS registrar. You should ask
-- your registrar to change the authoritative name servers for your domain to
-- the set of 'NameServers' elements returned in 'DelegationSet'.
chzName :: Lens' CreateHostedZone Text
chzName = lens _chzName (\s a -> s { _chzName = a })

-- | The VPC that you want your hosted zone to be associated with. By providing
-- this parameter, your newly created hosted cannot be resolved anywhere other
-- than the given VPC.
chzVPC :: Lens' CreateHostedZone (Maybe VPC)
chzVPC = lens _chzVPC (\s a -> s { _chzVPC = a })

data CreateHostedZoneResponse = CreateHostedZoneResponse
    { _chzrChangeInfo    :: ChangeInfo
    , _chzrDelegationSet :: DelegationSet
    , _chzrHostedZone    :: HostedZone
    , _chzrLocation      :: Text
    , _chzrVPC           :: Maybe VPC
    } deriving (Eq, Read, Show)

-- | 'CreateHostedZoneResponse' constructor.
--
-- The fields accessible through corresponding lenses are:
--
-- * 'chzrChangeInfo' @::@ 'ChangeInfo'
--
-- * 'chzrDelegationSet' @::@ 'DelegationSet'
--
-- * 'chzrHostedZone' @::@ 'HostedZone'
--
-- * 'chzrLocation' @::@ 'Text'
--
-- * 'chzrVPC' @::@ 'Maybe' 'VPC'
--
createHostedZoneResponse :: HostedZone -- ^ 'chzrHostedZone'
                         -> ChangeInfo -- ^ 'chzrChangeInfo'
                         -> DelegationSet -- ^ 'chzrDelegationSet'
                         -> Text -- ^ 'chzrLocation'
                         -> CreateHostedZoneResponse
createHostedZoneResponse p1 p2 p3 p4 = CreateHostedZoneResponse
    { _chzrHostedZone    = p1
    , _chzrChangeInfo    = p2
    , _chzrDelegationSet = p3
    , _chzrLocation      = p4
    , _chzrVPC           = Nothing
    }

-- | A complex type that contains information about the request to create a hosted
-- zone. This includes an ID that you use when you call the 'GetChange' action to
-- get the current status of the change request.
chzrChangeInfo :: Lens' CreateHostedZoneResponse ChangeInfo
chzrChangeInfo = lens _chzrChangeInfo (\s a -> s { _chzrChangeInfo = a })

-- | A complex type that contains name server information.
chzrDelegationSet :: Lens' CreateHostedZoneResponse DelegationSet
chzrDelegationSet =
    lens _chzrDelegationSet (\s a -> s { _chzrDelegationSet = a })

-- | A complex type that contains identifying information about the hosted zone.
chzrHostedZone :: Lens' CreateHostedZoneResponse HostedZone
chzrHostedZone = lens _chzrHostedZone (\s a -> s { _chzrHostedZone = a })

-- | The unique URL representing the new hosted zone.
chzrLocation :: Lens' CreateHostedZoneResponse Text
chzrLocation = lens _chzrLocation (\s a -> s { _chzrLocation = a })

chzrVPC :: Lens' CreateHostedZoneResponse (Maybe VPC)
chzrVPC = lens _chzrVPC (\s a -> s { _chzrVPC = a })

instance ToPath CreateHostedZone where
    toPath = const "/2013-04-01/hostedzone"

instance ToQuery CreateHostedZone where
    toQuery = const mempty

instance ToHeaders CreateHostedZone

instance ToXMLRoot CreateHostedZone where
    toXMLRoot CreateHostedZone{..} = namespaced ns "CreateHostedZone"
        [ "Name"             =@ _chzName
        , "VPC"              =@ _chzVPC
        , "CallerReference"  =@ _chzCallerReference
        , "HostedZoneConfig" =@ _chzHostedZoneConfig
        , "DelegationSetId"  =@ _chzDelegationSetId
        ]

instance ToXML CreateHostedZone

instance AWSRequest CreateHostedZone where
    type Sv CreateHostedZone = Route53
    type Rs CreateHostedZone = CreateHostedZoneResponse

    request  = post
    response = xmlHeaderResponse $ \h x -> CreateHostedZoneResponse
        <$> x .@  "ChangeInfo"
        <*> x .@  "DelegationSet"
        <*> x .@  "HostedZone"
        <*> h ~:  "Location"
        <*> x .@? "VPC"
