package com.microsoft.azure.management.appservice.implementation;
import com.microsoft.azure.management.apigeneration.LangDefinition;
import com.microsoft.azure.management.appservice.AppServiceDomain;
import com.microsoft.azure.management.appservice.AzureResourceType;
import com.microsoft.azure.management.appservice.CustomHostNameDnsRecordType;
import com.microsoft.azure.management.appservice.DeploymentSlot;
import com.microsoft.azure.management.appservice.HostNameBinding;
import com.microsoft.azure.management.appservice.HostNameType;
import com.microsoft.azure.management.appservice.WebAppBase;
import com.microsoft.azure.management.resources.fluentcore.arm.Region;
import com.microsoft.azure.management.resources.fluentcore.model.Creatable;
import com.microsoft.azure.management.resources.fluentcore.model.Indexable;
import com.microsoft.azure.management.resources.fluentcore.model.implementation.IndexableWrapperImpl;
import com.microsoft.azure.management.resources.fluentcore.utils.Utils;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import rx.Observable;
import rx.functions.Func1;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@LangDefinition(ContainerName = "/Microsoft.Azure.Management.AppService.Fluent")
class HostNameBindingImpl<
FluentT extends WebAppBase,
FluentImplT extends WebAppBaseImpl<FluentT, FluentImplT>>
extends
IndexableWrapperImpl<HostNameBindingInner>
implements
Creatable<HostNameBinding>,
HostNameBinding,
HostNameBinding.Definition<WebAppBase.DefinitionStages.WithCreate<FluentT>>,
HostNameBinding.UpdateDefinition<WebAppBase.Update<FluentT>> {
private final FluentImplT parent;
private String domainName;
private String name;
HostNameBindingImpl(HostNameBindingInner innerObject, FluentImplT parent) {
super(innerObject);
this.parent = parent;
this.name = innerObject.name();
if (name != null && name.contains("/")) {
this.name = name.replace(parent.name() + "/", "");
}
}
@Override
public String id() {
return inner().id();
}
@Override
public String type() {
return inner().type();
}
@Override
public String regionName() {
return parent().regionName();
}
@Override
public Region region() {
return parent().region();
}
@Override
public Map<String, String> tags() {
return parent().tags();
}
@Override
public String webAppName() {
return inner().siteName();
}
@Override
public String domainId() {
return inner().domainId();
}
@Override
public String azureResourceName() {
return inner().azureResourceName();
}
@Override
public AzureResourceType azureResourceType() {
return inner().azureResourceType();
}
@Override
public CustomHostNameDnsRecordType dnsRecordType() {
return inner().customHostNameDnsRecordType();
}
@Override
public HostNameType hostNameType() {
return inner().hostNameType();
}
@Override
public FluentImplT attach() {
parent.withHostNameBinding(this);
return parent;
}
@Override
public HostNameBindingImpl<FluentT, FluentImplT> withDnsRecordType(CustomHostNameDnsRecordType hostNameDnsRecordType) {
Pattern pattern = Pattern.compile("([.\\w-]+)\\.([\\w-]+\\.\\w+)");
Matcher matcher = pattern.matcher(name);
if (hostNameDnsRecordType == CustomHostNameDnsRecordType.CNAME && !matcher.matches()) {
throw new IllegalArgumentException("root hostname cannot be assigned with a CName record");
}
inner().withCustomHostNameDnsRecordType(hostNameDnsRecordType);
return this;
}
@Override
public HostNameBindingImpl<FluentT, FluentImplT> refresh() {
return this;
}
@Override
public Observable<HostNameBinding> refreshAsync() {
final HostNameBindingImpl<FluentT, FluentImplT> self = this;
Observable<HostNameBindingInner> observable = null;
if (parent instanceof DeploymentSlot) {
observable = this.parent().manager().inner().webApps().getHostNameBindingSlotAsync(
parent().resourceGroupName(), ((DeploymentSlot) parent).parent().name(), parent().name(), name());
} else {
observable = this.parent().manager().inner().webApps().getHostNameBindingAsync(parent().resourceGroupName(),
parent().name(), name());
}
return observable.map(new Func1<HostNameBindingInner, HostNameBinding>() {
@Override
public HostNameBinding call(HostNameBindingInner hostNameBindingInner) {
self.setInner(hostNameBindingInner);
return self;
}
});
}
@Override
public HostNameBinding create() {
createAsync().toBlocking().subscribe();
return this;
}
@Override
public ServiceFuture<HostNameBinding> createAsync(ServiceCallback<HostNameBinding> callback) {
Observable<Indexable> indexableObservable = createAsync();
return ServiceFuture.fromBody(Utils.<HostNameBinding>rootResource(indexableObservable), callback);
}
@Override
public Observable<Indexable> createAsync() {
final HostNameBinding self = this;
Func1<HostNameBindingInner, HostNameBinding> mapper = new Func1<HostNameBindingInner, HostNameBinding>() {
@Override
public HostNameBinding call(HostNameBindingInner hostNameBindingInner) {
setInner(hostNameBindingInner);
return self;
}
};
Observable<HostNameBinding> hostNameBindingObservable;
if (parent instanceof DeploymentSlot) {
hostNameBindingObservable = this.parent().manager().inner().webApps().createOrUpdateHostNameBindingSlotAsync(
parent().resourceGroupName(),
((DeploymentSlot) parent).parent().name(),
name,
parent().name(), inner()).map(mapper);
} else {
hostNameBindingObservable = this.parent().manager().inner().webApps().createOrUpdateHostNameBindingAsync(
parent().resourceGroupName(), parent().name(), name, inner()).map(mapper);
}
return hostNameBindingObservable.map(new Func1<HostNameBinding, Indexable>() {
@Override
public Indexable call(HostNameBinding hostNameBinding) {
return hostNameBinding;
}
});
}
private String normalizeHostNameBindingName(String hostname, String domainName) {
if (!hostname.endsWith(domainName)) {
hostname = hostname + "." + domainName;
}
if (hostname.startsWith("@")) {
hostname = hostname.replace("@.", "");
}
return hostname;
}
@Override
public HostNameBindingImpl<FluentT, FluentImplT> withAzureManagedDomain(AppServiceDomain domain) {
inner().withDomainId(domain.id());
inner().withHostNameType(HostNameType.MANAGED);
this.domainName = domain.name();
return this;
}
@Override
public HostNameBindingImpl<FluentT, FluentImplT> withThirdPartyDomain(String domain) {
inner().withHostNameType(HostNameType.VERIFIED);
this.domainName = domain;
return this;
}
@Override
public String toString() {
String suffix;
if (azureResourceType() == AzureResourceType.TRAFFIC_MANAGER) {
suffix = ".trafficmanager.net";
} else {
suffix = ".azurewebsites.net";
}
return name + ": " + dnsRecordType() + " " + azureResourceName() + suffix;
}
@Override
public String name() {
return name;
}
@Override
public WebAppBase parent() {
return parent;
}
@Override
public HostNameBindingImpl<FluentT, FluentImplT> withSubDomain(String subDomain) {
this.name = normalizeHostNameBindingName(subDomain, domainName);
return this;
}
}