package com.platform.kubernetes;

import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ContainerPort;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.ReplicationController;
import io.fabric8.kubernetes.api.model.Volume;
import io.fabric8.kubernetes.api.model.VolumeMount;
import io.fabric8.kubernetes.client.Client;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.platform.utils.Configs;
import com.platform.utils.UtilsHelper;

public class SimpleKubeClient {
	private KubernetesClient client;
	private final static String DEFAULT_NAMESPACE = "default";

	public SimpleKubeClient() {
		this.client = new DefaultKubernetesClient(Configs.KUBE_MASTER_URL);
	}

	public SimpleKubeClient(String masterUrl) {
		this.client = new DefaultKubernetesClient(masterUrl);
	}

	public SimpleKubeClient(Config config) {
		Config cf = config;
		if (null == config) {
			cf = new ConfigBuilder().withMasterUrl(Configs.KUBE_MASTER_URL)
					.build();
		}

		this.client = new DefaultKubernetesClient(cf);
	}

	// RollingUpdatercline

	public void updateOrAddReplicasLabelById(String namespace,
			String resourceId, String key, String value) {
		KubernetesClient kubeClient = client;
		if (checkClientNull())
			kubeClient = new DefaultKubernetesClient(Configs.KUBE_MASTER_URL);
		kubeClient.replicationControllers().inNamespace(namespace)
				.withName(resourceId).rolling().edit().editMetadata()
				.addToLabels(key, value).endMetadata().done();
	}

	public void updateOrAddReplicasLabelByEntity(String namespace,
			ReplicationController replicas, String key, String value) {
		updateOrAddReplicasLabelById(namespace, replicas.getMetadata()
				.getName(), key, value);
	}

	public void updateOrAddReplicasLabelById(String resourceId, String key,
			String value) {
		updateOrAddReplicasLabelById(DEFAULT_NAMESPACE, resourceId, key, value);
	}

	public void updateOrAddReplicasLabelByEntity(
			ReplicationController replicas, String key, String value) {
		updateOrAddReplicasLabelByEntity(DEFAULT_NAMESPACE, replicas, key,
				value);
	}

	@SuppressWarnings("resource")
	public ReplicationController getReplicationController(String namespace,
			String replicasName) {
		KubernetesClient kubeClient = client;
		if (checkClientNull())
			kubeClient = new DefaultKubernetesClient(Configs.KUBE_MASTER_URL);
		return kubeClient.replicationControllers().inNamespace(namespace)
				.withName(replicasName).get();
	}

	public ReplicationController getReplicationController(String replicasName) {
		return getReplicationController(DEFAULT_NAMESPACE, replicasName);
	}

	@SuppressWarnings("resource")
	public List<Pod> getPodsForApplicaList(ReplicationController rc) {
		Map<String, String> selector = rc.getSpec().getSelector();
		KubernetesClient kubeClient = client;
		if (checkClientNull())
			kubeClient = new DefaultKubernetesClient(Configs.KUBE_MASTER_URL);
		List<Pod> podList = kubeClient.pods()
				.inNamespace(rc.getMetadata().getNamespace()).list().getItems();
		return getPods(podList, selector);
	}

	private boolean checkClientNull() {
		return null == client;
	}

	public List<Pod> getPods(List<Pod> pods, Map<String, String> selector) {
		List<Pod> result = new ArrayList<Pod>();
		for (int i = 0; i < pods.size(); i++)
			if (UtilsHelper.isSubMap(getLabels(pods.get(i)), selector))
				result.add(pods.get(i));
		return result;
	}

	private Map<String, String> getLabels(Pod pod) {
		return pod.getMetadata().getLabels();
	}

	public KubernetesClient getClient() {
		// TODO Auto-generated method stub
		return client;
	}

	public int getPodContainerport(Pod pod) {
		int port = Configs.ORACLE_DEFAULT_PORT;
		List<Container> containers = pod.getSpec().getContainers();
		if (null != containers && containers.size() > 0) {
			List<ContainerPort> ports = containers.get(0).getPorts();
			if (null != ports && ports.size() > 0)
				port = ports.get(0).getHostPort();
		}
		return port;
	}

	public String getPodHostIp(Pod pod) {
		return pod.getSpec().getNodeName();
	}

	@SuppressWarnings("resource")
	public Map<String, ReplicationController> getReplicationControllerList(
			String namespace) {
		KubernetesClient kubeClient = client;
		Map<String, ReplicationController> rcMap = new HashMap<String, ReplicationController>();
		if (checkClientNull())
			kubeClient = new DefaultKubernetesClient(Configs.KUBE_MASTER_URL);
		List<ReplicationController> replicasList = kubeClient
				.replicationControllers().list().getItems();
		if (replicasList != null)
			for (int i = 0; i < replicasList.size(); i++) {
				ReplicationController rController = replicasList.get(i);
				rcMap.put(rController.getMetadata().getName(), rController);
			}
		return rcMap;
	}

	public Map<String, ReplicationController> getReplicationControllerList() {
		return getReplicationControllerList(DEFAULT_NAMESPACE);
	}

	public void close() {
		if (!checkClientNull())
			client.close();
	}

	/**
	 * 
	 * @param rcId --> 资源Id
	 * @param ns --> 资源名字空间
	 * @return
	 */
	public ReplicationController createReplicas(String rcId, String ns) {
		if (checkClientNull())
			client = new DefaultKubernetesClient(Configs.KUBE_MASTER_URL);
		ReplicationController rc = client.replicationControllers()
				.inNamespace(ns).createNew().editMetadata().withName(rcId)
				.endMetadata().done();
		return rc;
	}
	
	public ReplicationController createReplicas(String rcId, String ns, Map<String, String> selector,Volume volume, VolumeMount volumeMounts){
		if (checkClientNull())
			client = new DefaultKubernetesClient(Configs.KUBE_MASTER_URL);
		//Container container = new Container("", "", "", "", "", null, null, "oracle", ports, null, null, null, false, false, null, false, volumeMounts, null);
		//container.setName("oracle");
		//ReplicationController rController = client.replicationControllers().inNamespace(ns).createNew().editMetadata().withName(rcId).withLabels(selector).endMetadata().editSpec().withReplicas(1).withSelector(selector).editTemplate().editMetadata().withLabels(selector).endMetadata().editSpec().addNewContainer().a.
		return null;
	}
}
