class ZTSClient implements Closeable {

    static public InstanceRefreshRequest generateInstanceRefreshRequest(final String principalDomain,
            final String principalService, PrivateKey privateKey, final String csrDn,
            final String csrDomain, int expiryTime) {
        
        if (principalDomain == null || principalService == null) {
            throw new IllegalArgumentException("Principal's Domain and Service must be specified");
        }
        
        if (csrDomain == null) {
            throw new IllegalArgumentException("X509 CSR Domain must be specified");
        }
        
        // Athenz uses lower case for all elements, so let's
        // generate our dn which will be based on our service name
        
        final String domain = principalDomain.toLowerCase();
        final String service = principalService.toLowerCase();
        final String cn = domain + "." + service;
        
        String dn = "cn=" + cn;
        if (csrDn != null) {
            dn = dn.concat(",").concat(csrDn);
        }
        
        // now let's generate our dsnName field based on our principal's details

        final String hostName = service + '.' + domain.replace('.', '-') + '.' + csrDomain;
        
        GeneralName[] sanArray = new GeneralName[1];
        sanArray[0] = new GeneralName(GeneralName.dNSName, new DERIA5String(hostName));
        
        String csr;
        try {
            csr = Crypto.generateX509CSR(privateKey, dn, sanArray);
        } catch (OperatorCreationException | IOException ex) {
            throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
        }

        return new InstanceRefreshRequest().setCsr(csr).setExpiryTime(expiryTime);
    }

    public  ZTSClient();
    public  ZTSClient(String ztsUrl);
    public  ZTSClient(Principal identity);
    public  ZTSClient(String ztsUrl, Principal identity);
    public  ZTSClient(String ztsUrl, SSLContext sslContext);
    public  ZTSClient(String ztsUrl, String proxyUrl, SSLContext sslContext);
    public  ZTSClient(String domainName, String serviceName, ServiceIdentityProvider siaProvider);
    public  ZTSClient(String ztsUrl, String domainName, String serviceName,
                     ServiceIdentityProvider siaProvider);

}