package cz.xtf.openshift.builder;

import cz.xtf.TestConfiguration;
import cz.xtf.keystore.XTFKeyStore;
import cz.xtf.openshift.OpenshiftUtil;
import cz.xtf.util.RandomUtil;
import io.fabric8.openshift.api.model.Route;
import io.fabric8.openshift.api.model.RouteSpecBuilder;
import io.fabric8.openshift.api.model.TLSConfigBuilder;
import org.apache.commons.lang3.StringUtils;

public class RouteBuilder extends AbstractBuilder<Route, RouteBuilder> {
	private String hostName;
	private String serviceName;
	private String routeKey;
	private String routeCertificate;
	private String routeCA;
	private String serverCA;
	private TLSType tlsType;
	private int targetPort = 0;

	public static String createHostName(String appName) {
		return createHostName(appName, ".", ".");
	}

	public static String createHostName(String appName, String namespaceSeparator, String domainSeparator) {
		return String.format("%s%s%s%s%s",
				appName, namespaceSeparator, OpenshiftUtil.getInstance().getContext().getNamespace(), domainSeparator, TestConfiguration.routeDomain());
	}

	public static String createProxiedHostName(String appName) {
		return createProxiedHostName(appName, ".", ".");
	}

	public static String createProxiedHostName(String appName, String namespaceSeparator, String domainSeparator) {
		return String.format("%s%s%s%s%s%s%s",
				appName, namespaceSeparator, OpenshiftUtil.getInstance().getContext().getNamespace(), domainSeparator, TestConfiguration.routeDomain(), domainSeparator, TestConfiguration.proxyDomain());
	}

	// Workaround router issue with delete/create route with the same name
	private static String transformName(final String originalName) {
		return RandomUtil.generateUniqueId(originalName);
	}

	public RouteBuilder(String routeName) {
		this(null, transformName(routeName));
	}

	RouteBuilder(ApplicationBuilder applicationBuilder, String routeName) {
		super(applicationBuilder, transformName(routeName));
		tlsType = TLSType.NONE;
	}

	public RouteBuilder forService(String serviceName) {
		this.serviceName = serviceName;
		return this;
	}

	public RouteBuilder exposedAsHost(String hostName) {
		this.hostName = hostName;
		return this;
	}

	public RouteBuilder edge() {
		tlsType = TLSType.EDGE;
		return this;
	}

	public RouteBuilder passthrough() {
		tlsType = TLSType.PASSTHROUGH;
		return this;
	}

	public RouteBuilder reencrypt() {
		tlsType = TLSType.REENCRYPT;
		return this;
	}

	public RouteBuilder defaultRouteCA() {
		routeCA("authority");
		return this;
	}

	public RouteBuilder routeCA(String alias) {
		this.routeCA = XTFKeyStore.getInstance().getCertificate(alias);
		return this;
	}

	public RouteBuilder routeKey(String alias) {
		this.routeKey = XTFKeyStore.getInstance().getKey(alias);
		return this;
	}

	public RouteBuilder routeCertificate(String alias) {
		this.routeCertificate = XTFKeyStore.getInstance().getCertificate(alias);
		return this;
	}

	public RouteBuilder serverCA(String alias) {
		this.serverCA = XTFKeyStore.getInstance().getCertificate(alias);
		return this;
	}

	public RouteBuilder targetPort(int targetPort) {
		this.targetPort = targetPort;
		return this;
	}

	@Override
	public Route build() {
		RouteSpecBuilder spec = new RouteSpecBuilder()
				.withHost(hostName)
				.withNewTo()
				.withKind("Service")
				.withName(serviceName)
				.endTo();

		if (targetPort != 0) {
			spec.withNewPort().withNewTargetPort(targetPort).endPort();
		}

		if (tlsType != TLSType.NONE) {
			TLSConfigBuilder tls = new TLSConfigBuilder()
					.withTermination(tlsType.toString().toLowerCase());

			if (StringUtils.isNotBlank(routeKey)) {
				tls.withKey(routeKey);
			}
			if (StringUtils.isNotBlank(routeCertificate)) {
				tls.withCertificate(routeCertificate);
			}
			if (StringUtils.isNotBlank(routeCA)) {
				tls.withCaCertificate(routeCA);
			}
			if (StringUtils.isNotBlank(serverCA)) {
				tls.withDestinationCACertificate(serverCA);
			}
			spec.withTls(tls.build());
		}

		return new io.fabric8.openshift.api.model.RouteBuilder()
				.withMetadata(metadataBuilder().build())
				.withSpec(spec.build())
				.build();
	}

	@Override
	protected RouteBuilder getThis() {
		return this;
	}

	private enum TLSType {
		NONE, EDGE, PASSTHROUGH, REENCRYPT
	}
}

@@ -746,33 +746,33 @@
 tName(appName, %22
-.
+-
 %22, %22.%22);%0A%09%7D%0A%0A%09pu
@@ -1159,17 +1159,17 @@
 pName, %22
-.
+-
 %22, %22.%22);
@@ -1526,202 +1526,8 @@
 %09%7D%0A%0A
-%09// Workaround router issue with delete/create route with the same name%0A%09private static String transformName(final String originalName) %7B%0A%09%09return RandomUtil.generateUniqueId(originalName);%0A%09%7D%0A%0A
 %09pub
@@ -1576,30 +1576,16 @@
 s(null, 
-transformName(
 routeNam
@@ -1586,17 +1586,16 @@
 uteName)
-)
 ;%0A%09%7D%0A%0A%09R
@@ -1697,22 +1697,8 @@
 er, 
-transformName(
 rout
@@ -1703,17 +1703,16 @@
 uteName)
-)
 ;%0A%09%09tlsT

remove the transform workaround and use openshift defaults for default route hostnames