/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

#pragma once
#include <aws/core/utils/UUID.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/memory/stl/AWSVector.h>
#include <aws/ec2/EC2Request.h>
#include <aws/ec2/EC2_EXPORTS.h>
#include <aws/ec2/model/ConnectionTrackingSpecificationRequest.h>
#include <aws/ec2/model/InstanceIpv6Address.h>
#include <aws/ec2/model/Ipv4PrefixSpecificationRequest.h>
#include <aws/ec2/model/Ipv6PrefixSpecificationRequest.h>
#include <aws/ec2/model/NetworkInterfaceCreationType.h>
#include <aws/ec2/model/OperatorRequest.h>
#include <aws/ec2/model/PrivateIpAddressSpecification.h>
#include <aws/ec2/model/TagSpecification.h>

#include <utility>

namespace Aws {
namespace EC2 {
namespace Model {

/**
 */
class CreateNetworkInterfaceRequest : public EC2Request {
 public:
  AWS_EC2_API CreateNetworkInterfaceRequest() = default;

  // Service request name is the Operation name which will send this request out,
  // each operation should has unique request name, so that we can get operation's name from this request.
  // Note: this is not true for response, multiple operations may have the same response name,
  // so we can not get operation's name from response.
  inline virtual const char* GetServiceRequestName() const override { return "CreateNetworkInterface"; }

  AWS_EC2_API Aws::String SerializePayload() const override;

 protected:
  AWS_EC2_API void DumpBodyToUrl(Aws::Http::URI& uri) const override;

 public:
  ///@{
  /**
   * <p>The IPv4 prefixes assigned to the network interface.</p> <p>You can't specify
   * IPv4 prefixes if you've specified one of the following: a count of IPv4
   * prefixes, specific private IPv4 addresses, or a count of private IPv4
   * addresses.</p>
   */
  inline const Aws::Vector<Ipv4PrefixSpecificationRequest>& GetIpv4Prefixes() const { return m_ipv4Prefixes; }
  inline bool Ipv4PrefixesHasBeenSet() const { return m_ipv4PrefixesHasBeenSet; }
  template <typename Ipv4PrefixesT = Aws::Vector<Ipv4PrefixSpecificationRequest>>
  void SetIpv4Prefixes(Ipv4PrefixesT&& value) {
    m_ipv4PrefixesHasBeenSet = true;
    m_ipv4Prefixes = std::forward<Ipv4PrefixesT>(value);
  }
  template <typename Ipv4PrefixesT = Aws::Vector<Ipv4PrefixSpecificationRequest>>
  CreateNetworkInterfaceRequest& WithIpv4Prefixes(Ipv4PrefixesT&& value) {
    SetIpv4Prefixes(std::forward<Ipv4PrefixesT>(value));
    return *this;
  }
  template <typename Ipv4PrefixesT = Ipv4PrefixSpecificationRequest>
  CreateNetworkInterfaceRequest& AddIpv4Prefixes(Ipv4PrefixesT&& value) {
    m_ipv4PrefixesHasBeenSet = true;
    m_ipv4Prefixes.emplace_back(std::forward<Ipv4PrefixesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of IPv4 prefixes that Amazon Web Services automatically assigns to
   * the network interface.</p> <p>You can't specify a count of IPv4 prefixes if
   * you've specified one of the following: specific IPv4 prefixes, specific private
   * IPv4 addresses, or a count of private IPv4 addresses.</p>
   */
  inline int GetIpv4PrefixCount() const { return m_ipv4PrefixCount; }
  inline bool Ipv4PrefixCountHasBeenSet() const { return m_ipv4PrefixCountHasBeenSet; }
  inline void SetIpv4PrefixCount(int value) {
    m_ipv4PrefixCountHasBeenSet = true;
    m_ipv4PrefixCount = value;
  }
  inline CreateNetworkInterfaceRequest& WithIpv4PrefixCount(int value) {
    SetIpv4PrefixCount(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The IPv6 prefixes assigned to the network interface.</p> <p>You can't specify
   * IPv6 prefixes if you've specified one of the following: a count of IPv6
   * prefixes, specific IPv6 addresses, or a count of IPv6 addresses.</p>
   */
  inline const Aws::Vector<Ipv6PrefixSpecificationRequest>& GetIpv6Prefixes() const { return m_ipv6Prefixes; }
  inline bool Ipv6PrefixesHasBeenSet() const { return m_ipv6PrefixesHasBeenSet; }
  template <typename Ipv6PrefixesT = Aws::Vector<Ipv6PrefixSpecificationRequest>>
  void SetIpv6Prefixes(Ipv6PrefixesT&& value) {
    m_ipv6PrefixesHasBeenSet = true;
    m_ipv6Prefixes = std::forward<Ipv6PrefixesT>(value);
  }
  template <typename Ipv6PrefixesT = Aws::Vector<Ipv6PrefixSpecificationRequest>>
  CreateNetworkInterfaceRequest& WithIpv6Prefixes(Ipv6PrefixesT&& value) {
    SetIpv6Prefixes(std::forward<Ipv6PrefixesT>(value));
    return *this;
  }
  template <typename Ipv6PrefixesT = Ipv6PrefixSpecificationRequest>
  CreateNetworkInterfaceRequest& AddIpv6Prefixes(Ipv6PrefixesT&& value) {
    m_ipv6PrefixesHasBeenSet = true;
    m_ipv6Prefixes.emplace_back(std::forward<Ipv6PrefixesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of IPv6 prefixes that Amazon Web Services automatically assigns to
   * the network interface.</p> <p>You can't specify a count of IPv6 prefixes if
   * you've specified one of the following: specific IPv6 prefixes, specific IPv6
   * addresses, or a count of IPv6 addresses.</p>
   */
  inline int GetIpv6PrefixCount() const { return m_ipv6PrefixCount; }
  inline bool Ipv6PrefixCountHasBeenSet() const { return m_ipv6PrefixCountHasBeenSet; }
  inline void SetIpv6PrefixCount(int value) {
    m_ipv6PrefixCountHasBeenSet = true;
    m_ipv6PrefixCount = value;
  }
  inline CreateNetworkInterfaceRequest& WithIpv6PrefixCount(int value) {
    SetIpv6PrefixCount(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The type of network interface. The default is <code>interface</code>.</p>
   * <p>If you specify <code>efa-only</code>, do not assign any IP addresses to the
   * network interface. EFA-only network interfaces do not support IP addresses.</p>
   * <p>The only supported values are <code>interface</code>, <code>efa</code>,
   * <code>efa-only</code>, and <code>trunk</code>.</p>
   */
  inline NetworkInterfaceCreationType GetInterfaceType() const { return m_interfaceType; }
  inline bool InterfaceTypeHasBeenSet() const { return m_interfaceTypeHasBeenSet; }
  inline void SetInterfaceType(NetworkInterfaceCreationType value) {
    m_interfaceTypeHasBeenSet = true;
    m_interfaceType = value;
  }
  inline CreateNetworkInterfaceRequest& WithInterfaceType(NetworkInterfaceCreationType value) {
    SetInterfaceType(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The tags to apply to the new network interface.</p>
   */
  inline const Aws::Vector<TagSpecification>& GetTagSpecifications() const { return m_tagSpecifications; }
  inline bool TagSpecificationsHasBeenSet() const { return m_tagSpecificationsHasBeenSet; }
  template <typename TagSpecificationsT = Aws::Vector<TagSpecification>>
  void SetTagSpecifications(TagSpecificationsT&& value) {
    m_tagSpecificationsHasBeenSet = true;
    m_tagSpecifications = std::forward<TagSpecificationsT>(value);
  }
  template <typename TagSpecificationsT = Aws::Vector<TagSpecification>>
  CreateNetworkInterfaceRequest& WithTagSpecifications(TagSpecificationsT&& value) {
    SetTagSpecifications(std::forward<TagSpecificationsT>(value));
    return *this;
  }
  template <typename TagSpecificationsT = TagSpecification>
  CreateNetworkInterfaceRequest& AddTagSpecifications(TagSpecificationsT&& value) {
    m_tagSpecificationsHasBeenSet = true;
    m_tagSpecifications.emplace_back(std::forward<TagSpecificationsT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Unique, case-sensitive identifier that you provide to ensure the idempotency
   * of the request. For more information, see <a
   * href="https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-idempotency.html">Ensuring
   * idempotency</a>.</p>
   */
  inline const Aws::String& GetClientToken() const { return m_clientToken; }
  inline bool ClientTokenHasBeenSet() const { return m_clientTokenHasBeenSet; }
  template <typename ClientTokenT = Aws::String>
  void SetClientToken(ClientTokenT&& value) {
    m_clientTokenHasBeenSet = true;
    m_clientToken = std::forward<ClientTokenT>(value);
  }
  template <typename ClientTokenT = Aws::String>
  CreateNetworkInterfaceRequest& WithClientToken(ClientTokenT&& value) {
    SetClientToken(std::forward<ClientTokenT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>If you’re creating a network interface in a dual-stack or IPv6-only subnet,
   * you have the option to assign a primary IPv6 IP address. A primary IPv6 address
   * is an IPv6 GUA address associated with an ENI that you have enabled to use a
   * primary IPv6 address. Use this option if the instance that this ENI will be
   * attached to relies on its IPv6 address not changing. Amazon Web Services will
   * automatically assign an IPv6 address associated with the ENI attached to your
   * instance to be the primary IPv6 address. Once you enable an IPv6 GUA address to
   * be a primary IPv6, you cannot disable it. When you enable an IPv6 GUA address to
   * be a primary IPv6, the first IPv6 GUA will be made the primary IPv6 address
   * until the instance is terminated or the network interface is detached. If you
   * have multiple IPv6 addresses associated with an ENI attached to your instance
   * and you enable a primary IPv6 address, the first IPv6 GUA address associated
   * with the ENI becomes the primary IPv6 address.</p>
   */
  inline bool GetEnablePrimaryIpv6() const { return m_enablePrimaryIpv6; }
  inline bool EnablePrimaryIpv6HasBeenSet() const { return m_enablePrimaryIpv6HasBeenSet; }
  inline void SetEnablePrimaryIpv6(bool value) {
    m_enablePrimaryIpv6HasBeenSet = true;
    m_enablePrimaryIpv6 = value;
  }
  inline CreateNetworkInterfaceRequest& WithEnablePrimaryIpv6(bool value) {
    SetEnablePrimaryIpv6(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>A connection tracking specification for the network interface.</p>
   */
  inline const ConnectionTrackingSpecificationRequest& GetConnectionTrackingSpecification() const {
    return m_connectionTrackingSpecification;
  }
  inline bool ConnectionTrackingSpecificationHasBeenSet() const { return m_connectionTrackingSpecificationHasBeenSet; }
  template <typename ConnectionTrackingSpecificationT = ConnectionTrackingSpecificationRequest>
  void SetConnectionTrackingSpecification(ConnectionTrackingSpecificationT&& value) {
    m_connectionTrackingSpecificationHasBeenSet = true;
    m_connectionTrackingSpecification = std::forward<ConnectionTrackingSpecificationT>(value);
  }
  template <typename ConnectionTrackingSpecificationT = ConnectionTrackingSpecificationRequest>
  CreateNetworkInterfaceRequest& WithConnectionTrackingSpecification(ConnectionTrackingSpecificationT&& value) {
    SetConnectionTrackingSpecification(std::forward<ConnectionTrackingSpecificationT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Reserved for internal use.</p>
   */
  inline const OperatorRequest& GetOperator() const { return m_operator; }
  inline bool OperatorHasBeenSet() const { return m_operatorHasBeenSet; }
  template <typename OperatorT = OperatorRequest>
  void SetOperator(OperatorT&& value) {
    m_operatorHasBeenSet = true;
    m_operator = std::forward<OperatorT>(value);
  }
  template <typename OperatorT = OperatorRequest>
  CreateNetworkInterfaceRequest& WithOperator(OperatorT&& value) {
    SetOperator(std::forward<OperatorT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The ID of the subnet to associate with the network interface.</p>
   */
  inline const Aws::String& GetSubnetId() const { return m_subnetId; }
  inline bool SubnetIdHasBeenSet() const { return m_subnetIdHasBeenSet; }
  template <typename SubnetIdT = Aws::String>
  void SetSubnetId(SubnetIdT&& value) {
    m_subnetIdHasBeenSet = true;
    m_subnetId = std::forward<SubnetIdT>(value);
  }
  template <typename SubnetIdT = Aws::String>
  CreateNetworkInterfaceRequest& WithSubnetId(SubnetIdT&& value) {
    SetSubnetId(std::forward<SubnetIdT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>A description for the network interface.</p>
   */
  inline const Aws::String& GetDescription() const { return m_description; }
  inline bool DescriptionHasBeenSet() const { return m_descriptionHasBeenSet; }
  template <typename DescriptionT = Aws::String>
  void SetDescription(DescriptionT&& value) {
    m_descriptionHasBeenSet = true;
    m_description = std::forward<DescriptionT>(value);
  }
  template <typename DescriptionT = Aws::String>
  CreateNetworkInterfaceRequest& WithDescription(DescriptionT&& value) {
    SetDescription(std::forward<DescriptionT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The primary private IPv4 address of the network interface. If you don't
   * specify an IPv4 address, Amazon EC2 selects one for you from the subnet's IPv4
   * CIDR range. If you specify an IP address, you cannot indicate any IP addresses
   * specified in <code>privateIpAddresses</code> as primary (only one IP address can
   * be designated as primary).</p>
   */
  inline const Aws::String& GetPrivateIpAddress() const { return m_privateIpAddress; }
  inline bool PrivateIpAddressHasBeenSet() const { return m_privateIpAddressHasBeenSet; }
  template <typename PrivateIpAddressT = Aws::String>
  void SetPrivateIpAddress(PrivateIpAddressT&& value) {
    m_privateIpAddressHasBeenSet = true;
    m_privateIpAddress = std::forward<PrivateIpAddressT>(value);
  }
  template <typename PrivateIpAddressT = Aws::String>
  CreateNetworkInterfaceRequest& WithPrivateIpAddress(PrivateIpAddressT&& value) {
    SetPrivateIpAddress(std::forward<PrivateIpAddressT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The IDs of the security groups.</p>
   */
  inline const Aws::Vector<Aws::String>& GetGroups() const { return m_groups; }
  inline bool GroupsHasBeenSet() const { return m_groupsHasBeenSet; }
  template <typename GroupsT = Aws::Vector<Aws::String>>
  void SetGroups(GroupsT&& value) {
    m_groupsHasBeenSet = true;
    m_groups = std::forward<GroupsT>(value);
  }
  template <typename GroupsT = Aws::Vector<Aws::String>>
  CreateNetworkInterfaceRequest& WithGroups(GroupsT&& value) {
    SetGroups(std::forward<GroupsT>(value));
    return *this;
  }
  template <typename GroupsT = Aws::String>
  CreateNetworkInterfaceRequest& AddGroups(GroupsT&& value) {
    m_groupsHasBeenSet = true;
    m_groups.emplace_back(std::forward<GroupsT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The private IPv4 addresses.</p> <p>You can't specify private IPv4 addresses
   * if you've specified one of the following: a count of private IPv4 addresses,
   * specific IPv4 prefixes, or a count of IPv4 prefixes.</p>
   */
  inline const Aws::Vector<PrivateIpAddressSpecification>& GetPrivateIpAddresses() const { return m_privateIpAddresses; }
  inline bool PrivateIpAddressesHasBeenSet() const { return m_privateIpAddressesHasBeenSet; }
  template <typename PrivateIpAddressesT = Aws::Vector<PrivateIpAddressSpecification>>
  void SetPrivateIpAddresses(PrivateIpAddressesT&& value) {
    m_privateIpAddressesHasBeenSet = true;
    m_privateIpAddresses = std::forward<PrivateIpAddressesT>(value);
  }
  template <typename PrivateIpAddressesT = Aws::Vector<PrivateIpAddressSpecification>>
  CreateNetworkInterfaceRequest& WithPrivateIpAddresses(PrivateIpAddressesT&& value) {
    SetPrivateIpAddresses(std::forward<PrivateIpAddressesT>(value));
    return *this;
  }
  template <typename PrivateIpAddressesT = PrivateIpAddressSpecification>
  CreateNetworkInterfaceRequest& AddPrivateIpAddresses(PrivateIpAddressesT&& value) {
    m_privateIpAddressesHasBeenSet = true;
    m_privateIpAddresses.emplace_back(std::forward<PrivateIpAddressesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of secondary private IPv4 addresses to assign to a network
   * interface. When you specify a number of secondary IPv4 addresses, Amazon EC2
   * selects these IP addresses within the subnet's IPv4 CIDR range. You can't
   * specify this option and specify more than one private IP address using
   * <code>privateIpAddresses</code>.</p> <p>You can't specify a count of private
   * IPv4 addresses if you've specified one of the following: specific private IPv4
   * addresses, specific IPv4 prefixes, or a count of IPv4 prefixes.</p>
   */
  inline int GetSecondaryPrivateIpAddressCount() const { return m_secondaryPrivateIpAddressCount; }
  inline bool SecondaryPrivateIpAddressCountHasBeenSet() const { return m_secondaryPrivateIpAddressCountHasBeenSet; }
  inline void SetSecondaryPrivateIpAddressCount(int value) {
    m_secondaryPrivateIpAddressCountHasBeenSet = true;
    m_secondaryPrivateIpAddressCount = value;
  }
  inline CreateNetworkInterfaceRequest& WithSecondaryPrivateIpAddressCount(int value) {
    SetSecondaryPrivateIpAddressCount(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The IPv6 addresses from the IPv6 CIDR block range of your subnet.</p> <p>You
   * can't specify IPv6 addresses using this parameter if you've specified one of the
   * following: a count of IPv6 addresses, specific IPv6 prefixes, or a count of IPv6
   * prefixes.</p>
   */
  inline const Aws::Vector<InstanceIpv6Address>& GetIpv6Addresses() const { return m_ipv6Addresses; }
  inline bool Ipv6AddressesHasBeenSet() const { return m_ipv6AddressesHasBeenSet; }
  template <typename Ipv6AddressesT = Aws::Vector<InstanceIpv6Address>>
  void SetIpv6Addresses(Ipv6AddressesT&& value) {
    m_ipv6AddressesHasBeenSet = true;
    m_ipv6Addresses = std::forward<Ipv6AddressesT>(value);
  }
  template <typename Ipv6AddressesT = Aws::Vector<InstanceIpv6Address>>
  CreateNetworkInterfaceRequest& WithIpv6Addresses(Ipv6AddressesT&& value) {
    SetIpv6Addresses(std::forward<Ipv6AddressesT>(value));
    return *this;
  }
  template <typename Ipv6AddressesT = InstanceIpv6Address>
  CreateNetworkInterfaceRequest& AddIpv6Addresses(Ipv6AddressesT&& value) {
    m_ipv6AddressesHasBeenSet = true;
    m_ipv6Addresses.emplace_back(std::forward<Ipv6AddressesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of IPv6 addresses to assign to a network interface. Amazon EC2
   * automatically selects the IPv6 addresses from the subnet range.</p> <p>You can't
   * specify a count of IPv6 addresses using this parameter if you've specified one
   * of the following: specific IPv6 addresses, specific IPv6 prefixes, or a count of
   * IPv6 prefixes.</p> <p>If your subnet has the
   * <code>AssignIpv6AddressOnCreation</code> attribute set, you can override that
   * setting by specifying 0 as the IPv6 address count.</p>
   */
  inline int GetIpv6AddressCount() const { return m_ipv6AddressCount; }
  inline bool Ipv6AddressCountHasBeenSet() const { return m_ipv6AddressCountHasBeenSet; }
  inline void SetIpv6AddressCount(int value) {
    m_ipv6AddressCountHasBeenSet = true;
    m_ipv6AddressCount = value;
  }
  inline CreateNetworkInterfaceRequest& WithIpv6AddressCount(int value) {
    SetIpv6AddressCount(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Checks whether you have the required permissions for the action, without
   * actually making the request, and provides an error response. If you have the
   * required permissions, the error response is <code>DryRunOperation</code>.
   * Otherwise, it is <code>UnauthorizedOperation</code>.</p>
   */
  inline bool GetDryRun() const { return m_dryRun; }
  inline bool DryRunHasBeenSet() const { return m_dryRunHasBeenSet; }
  inline void SetDryRun(bool value) {
    m_dryRunHasBeenSet = true;
    m_dryRun = value;
  }
  inline CreateNetworkInterfaceRequest& WithDryRun(bool value) {
    SetDryRun(value);
    return *this;
  }
  ///@}
 private:
  Aws::Vector<Ipv4PrefixSpecificationRequest> m_ipv4Prefixes;

  int m_ipv4PrefixCount{0};

  Aws::Vector<Ipv6PrefixSpecificationRequest> m_ipv6Prefixes;

  int m_ipv6PrefixCount{0};

  NetworkInterfaceCreationType m_interfaceType{NetworkInterfaceCreationType::NOT_SET};

  Aws::Vector<TagSpecification> m_tagSpecifications;

  Aws::String m_clientToken{Aws::Utils::UUID::PseudoRandomUUID()};

  bool m_enablePrimaryIpv6{false};

  ConnectionTrackingSpecificationRequest m_connectionTrackingSpecification;

  OperatorRequest m_operator;

  Aws::String m_subnetId;

  Aws::String m_description;

  Aws::String m_privateIpAddress;

  Aws::Vector<Aws::String> m_groups;

  Aws::Vector<PrivateIpAddressSpecification> m_privateIpAddresses;

  int m_secondaryPrivateIpAddressCount{0};

  Aws::Vector<InstanceIpv6Address> m_ipv6Addresses;

  int m_ipv6AddressCount{0};

  bool m_dryRun{false};
  bool m_ipv4PrefixesHasBeenSet = false;
  bool m_ipv4PrefixCountHasBeenSet = false;
  bool m_ipv6PrefixesHasBeenSet = false;
  bool m_ipv6PrefixCountHasBeenSet = false;
  bool m_interfaceTypeHasBeenSet = false;
  bool m_tagSpecificationsHasBeenSet = false;
  bool m_clientTokenHasBeenSet = true;
  bool m_enablePrimaryIpv6HasBeenSet = false;
  bool m_connectionTrackingSpecificationHasBeenSet = false;
  bool m_operatorHasBeenSet = false;
  bool m_subnetIdHasBeenSet = false;
  bool m_descriptionHasBeenSet = false;
  bool m_privateIpAddressHasBeenSet = false;
  bool m_groupsHasBeenSet = false;
  bool m_privateIpAddressesHasBeenSet = false;
  bool m_secondaryPrivateIpAddressCountHasBeenSet = false;
  bool m_ipv6AddressesHasBeenSet = false;
  bool m_ipv6AddressCountHasBeenSet = false;
  bool m_dryRunHasBeenSet = false;
};

}  // namespace Model
}  // namespace EC2
}  // namespace Aws
