The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
package WWW::eNom::Role::Commands;

use Moo::Role;
use strict;
use warnings;
use utf8;

use Class::Method::Modifiers 2.04 qw(fresh);
use HTTP::Tiny 0.031;
use XML::LibXML::Simple 0.91 qw(XMLin);

our $VERSION = 'v1.2.8'; # VERSION

requires "_make_query_string";

=begin Pod::Coverage

 \w+

=end Pod::Coverage

=cut

# Create methods to support eNom API version 7.8:
my @commands = qw(
    AddBulkDomains AddContact AddDomainFolder AddDomainHeader AddHostHeader
    AddToCart AdvancedDomainSearch AM_AutoRenew AM_Configure AM_GetAccountDetail
    AM_GetAccounts AM_Renew AssignToDomainFolder AuthorizeTLD
    CalculateAllHostPackagePricing CalculateHostPackagePricing CancelHostAccount
    CertChangeApproverEmail CertConfigureCert CertGetApproverEmail
    CertGetCertDetail CertGetCerts CertModifyOrder CertParseCSR CertReissueCert
    CertPurchaseCert CertResendApproverEmail CertResendFulfillmentEmail Check
    CheckLogin CheckNSStatus CommissionAccount Contacts CreateAccount
    CreateHostAccount CreateSubAccount DeleteAllPOPPaks DeleteContact
    DeleteCustomerDefinedData DeleteDomainFolder DeleteDomainHeader
    DeleteFromCart DeleteHostedDomain DeleteHostHeader DeleteNameServer
    DeletePOP3 DeletePOPPak DeleteRegistration DeleteSubaccount DisableFolderApp
    DisableServices EnableFolderApp EnableServices Extend Extend_RGP
    ExtendDomainDNS Forwarding GetAccountInfo GetAccountPassword
    GetAccountValidation GetAddressBook GetAgreementPage GetAllAccountInfo
    GetAllDomains GetAllHostAccounts GetAllResellerHostPricing GetBalance
    GetCartContent GetCatchAll GetCerts GetConfirmationSettings GetContacts
    GetCusPreferences GetCustomerDefinedData GetCustomerPaymentInfo GetDNS
    GetDNSStatus GetDomainCount GetDomainExp GetDomainFolderDetail
    GetDomainFolderList GetDomainHeader GetDomainInfo GetDomainNameID GetDomains
    GetDomainServices GetDomainSLDTLD GetDomainSRVHosts GetDomainStatus
    GetDomainSubServices GetDotNameForwarding GetExpiredDomains GetExtAttributes
    GetExtendInfo GetFilePermissions GetForwarding GetGlobalChangeStatus
    GetGlobalChangeStatusDetail GetHomeDomainList GetHostAccount GetHostAccounts
    GetHostHeader GetHosts GetIDNCodes GetIPResolver GetMailHosts GetMetaTag
    GetNews GetOrderDetail GetOrderList GetPasswordBit GetPOP3 GetPOPExpirations
    GetPOPForwarding GetProductNews GetProductSelectionList GetRegHosts
    GetRegistrationStatus GetRegLock GetRenew GetReport GetResellerHostPricing
    GetResellerInfo GetServiceContact GetSPFHosts GetStorageUsage
    GetSubAccountDetails GetSubAccountPassword GetSubAccounts
    GetSubaccountsDetailList GetTLDList GetTransHistory GetWebHostingAll
    GetWhoisContact GetWPPSInfo GM_CancelSubscription GM_CheckDomain
    GM_GetCancelReasons GM_GetControlPanelLoginURL GM_GetRedirectScript
    GM_GetStatuses GM_GetSubscriptionDetails GM_GetSubscriptions
    GM_ReactivateSubscription GM_RenewSubscription GM_UpdateBillingCycle
    GM_UpdateSubscriptionDetails HostPackageDefine HostPackageDelete
    HostPackageModify HostPackageView HostParkingPage InsertNewOrder
    IsFolderEnabled ListDomainHeaders ListHostHeaders ListWebFiles
    MetaBaseGetValue MetaBaseSetValue ModifyDomainHeader ModifyHostHeader
    ModifyNS ModifyNSHosting ModifyPOP3 MySQL_GetDBInfo NameSpinner
    NM_CancelOrder NM_ExtendOrder NM_GetPremiumDomainSettings
    NM_GetSearchCategories NM_ProcessOrder NM_Search
    NM_SetPremiumDomainSettings ParseDomain PE_GetCustomerPricing
    PE_GetDomainPricing PE_GetPOPPrice PE_GetProductPrice PE_GetResellerPrice
    PE_GetRetailPrice PE_GetRetailPricing PE_GetRocketPrice PE_GetTLDID
    PE_SetPricing PP_CancelSubscription PP_CheckUpgrade PP_GetCancelReasons
    PP_GetControlPanelLoginURL PP_GetStatuses PP_GetSubscriptionDetails
    PP_GetSubscriptions PP_ReactivateSubscription PP_UpdateSubscriptionDetails
    PP_ValidatePassword Portal_GetToken PreConfigure Purchase PurchaseHosting
    PurchasePOPBundle PurchasePreview PurchaseServices PushDomain
    RC_CancelSubscription RC_FreeTrialCheck RC_GetLoginToken
    RC_GetSubscriptionDetails RC_GetSubscriptions RC_RebillSubscription
    RC_ResetPassword RC_SetBillingCycle RC_SetPassword RC_SetSubscriptionDomain
    RC_SetSubscriptionName RefillAccount RegisterNameServer RemoveTLD
    RemoveUnsyncedDomains RenewPOPBundle RenewServices RP_CancelAccount
    RP_GetAccountDetail RP_GetAccounts RP_GetUpgradeOptions RP_GetUpgradePrice
    RP_RebillAccount RP_UpdateAccountName RP_UpgradeAccount RP_ValidateEmail
    RPT_GetReport SendAccountEmail ServiceSelect SetCatchAll
    SetCustomerDefinedData SetDNSHost SetDomainSRVHosts SetDomainSubServices
    SetDotNameForwarding SetFilePermissions SetHosts SetIPResolver SetPakRenew
    SetPassword SetPOPForwarding SetRegLock SetRenew SetResellerServicesPricing
    SetResellerTLDPricing SetSPFHosts SetUpPOP3User SL_AutoRenew SL_Configure
    SL_GetAccountDetail SL_GetAccounts StatusDomain SubAccountDomains
    SynchAuthInfo TEL_AddCTHUser TEL_GetCTHUserInfo TEL_GetCTHUserList
    TEL_GetPrivacy TEL_IsCTHUser TEL_UpdateCTHUser TEL_UpdatePrivacy
    TLD_AddWatchlist TLD_DeleteWatchlist TLD_GetTLD TLD_GetWatchlist
    TLD_GetWatchlistTlds TP_CancelOrder TP_CreateOrder TP_GetDetailsByDomain
    TP_GetOrder TP_GetOrderDetail TP_GetOrderReview TP_GetOrdersByDomain
    TP_GetOrderStatuses TP_GetTLDInfo TP_ResendEmail TP_ResubmitLocked
    TP_SubmitOrder TP_UpdateOrderDetail TS_AutoRenew TS_Configure
    TS_GetAccountDetail TS_GetAccounts UpdateAccountInfo UpdateAccountPricing
    UpdateCart UpdateCusPreferences UpdateDomainFolder UpdateExpiredDomains
    UpdateHostPackagePricing UpdateMetaTag UpdateNameServer
    UpdateNotificationAmount UpdatePushList UpdateRenewalSettings
    ValidatePassword WBLConfigure WBLGetCategories WBLGetFields WBLGetStatus
    WebHostCreateDirectory WebHostCreatePOPBox WebHostDeletePOPBox
    WebHostGetCartItem WebHostGetOverageOptions WebHostGetOverages
    WebHostGetPackageComponentList WebHostGetPackageMinimums WebHostGetPackages
    WebHostGetPOPBoxes WebHostGetResellerPackages WebHostGetStats
    WebHostHelpInfo WebHostSetCustomPackage WebHostSetOverageOptions
    WebHostUpdatePassword WebHostUpdatePOPPassword WSC_GetAccountInfo
    WSC_GetAllPackages WSC_GetPricing WSC_Update_Ops XXX_GetMemberId
    XXX_RemoveMemberId XXX_SetMemberId
    GetDomainAuthInfo
);

my $ua = HTTP::Tiny->new;
for my $command (@commands) {
    fresh $command => sub {
        my ($self, @opts) = @_;
        my $uri = $self->_make_query_string($command, @opts);
        my $response = $ua->get($uri)->{content};
        my $response_type = $self->response_type;
        if ( $response_type eq "xml_simple" ) {
            $response = XMLin($response);
            $response->{errors} &&= [ values %{ $response->{errors} } ];
            $response->{responses} &&= $response->{responses}{response};
            $response->{responses} = [ $response->{responses} ]
                if $response->{ResponseCount} == 1;
            foreach my $key ( keys %{$response} ) {
                next unless $key =~ /(.*?)(\d+)$/;
                $response->{$1} = undef if ref $response->{$key};
                $response->{$1}[ $2 - 1 ] = delete $response->{$key};
            }
        }
        return $response;
    };
}

1;