package com.bocloud.ims.service.resource.kubernetes;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.kubernetes.SecretDriver;
import com.bocloud.cmp.model.kubernetes.SecretModel;
import com.bocloud.common.encrypt.AESEncrptor;
import com.bocloud.common.encrypt.Encryptor;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Pager;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.model.Sign;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.Harbor;
import com.bocloud.ims.entity.resource.kubernetes.KubeNamespace;
import com.bocloud.ims.entity.resource.kubernetes.KubeSecret;
import com.bocloud.ims.entity.resource.kubernetes.KubeService;
import com.bocloud.ims.interfaces.resource.kubernetes.KubeSecretService;
import com.bocloud.ims.repository.kubernetes.KubeNamespaceRepository;
import com.bocloud.ims.repository.kubernetes.KubeSecretRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.HarborRepository;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service("kubeSecretService")
public class KubeSecretServiceImpl implements KubeSecretService {

	private static final Logger logger = LoggerFactory.getLogger(KubeSecretServiceImpl.class);
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private KubeSecretRepository kubeSecretRepository;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private HarborRepository harborRepository;
	@Autowired
	private SecretDriver secretDriver;
	@Autowired
	private KubeNamespaceRepository kubeNamespaceRepository;

	@Override
	public BocloudResult list(Pager pager, RequestContext context) {
		GridBean gridBean = null;
		try {
			List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
			Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap());
			Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false);
			sorter.put("gmtCreate", Common.ONE);
			Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
			Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);

			int total = 0;
			Long tenantId = context.getTenant();
			if (null != tenantId && 0 != tenantId) {
				params.add(new Param(MapTools.simpleMap(Common.TENANTID, tenantId), Sign.EQ));
			}
			// 为租户下的用户
			List<KubeSecret> list = null;
			if (null != tenantId && 0L != tenantId) {
				total = this.kubeSecretRepository.count(params, null);
				list = this.kubeSecretRepository.list(page, rows, params, sorter, null);
				gridBean = GridHelper.getBean(page, rows, total, list);
			} else {
				total = this.kubeSecretRepository.count(params);
				if (simple) {
					List<SimpleBean> beans = this.kubeSecretRepository.list(params, sorter);
					gridBean = new GridBean(1, 1, total, beans);
				} else {
					list = this.kubeSecretRepository.list(page, rows, params, sorter);
					gridBean = GridHelper.getBean(page, rows, total, list);
				}
			}
			return new BocloudResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query service list fail:", e);
			return new BocloudResult(false, "查询失败");
		}
	}

	@Override
	public BocloudResult create(KubeSecret kubeSecret, RequestContext context) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(kubeSecret.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取集群信息失败");
			}
			Long nsId = kubeSecret.getNsId();
			KubeNamespace kubeNamespace = kubeNamespaceRepository.query(nsId);
			if (null == kubeNamespace) {
				return new BocloudResult(false, "应用信息异常！");
			}
			Long harborId = kubeSecret.getHarborId();
			Harbor harbor = harborRepository.query(harborId);
			if (null == harbor) {
				return new BocloudResult(false, "镜像仓库信息异常！");
			}
			String secretTemplate = "";// socSystemConfigService.getByCode("KubeSecretTemplate");
			String dockerconfigjson = authInfo(secretTemplate, harbor);
			if (StringUtils.isEmpty(dockerconfigjson)) {
				return new BocloudResult(false, "认证信息异常！");
			}
			SecretModel model = new SecretModel();
			BeanUtils.copyProperties(kubeSecret, model);
			model.setNamespace(kubeNamespace.getName());
			model.setDockerconfigjson(dockerconfigjson);
			Map<String, String> lablesMap = new HashMap<String, String>();
			lablesMap.put("registryId", harborId + "");
			lablesMap.put("registryType", "harbor");
			model.setLablesMap(lablesMap);
			BocloudResult bocloudResult = secretDriver.create(vendor.getUuid(), model);
			if (bocloudResult.isFailed()) {
				return bocloudResult;
			}
			SecretModel secretModel = JSONObject.parseObject(JSON.toJSONString(bocloudResult.getData()),
					SecretModel.class);
			BeanUtils.copyProperties(secretModel, kubeSecret);
			kubeSecret.setAppId(kubeNamespace.getId());
			kubeSecret.setAppName(kubeNamespace.getName());
			kubeSecret.setCreatorId(context.getTarget());
			kubeSecret.setTenantId(context.getTenant());
			kubeSecretRepository.save(kubeSecret);
			return new BocloudResult(true, "添加成功");
		} catch (Exception e) {
			logger.error("create service error", e);
			return new BocloudResult(false, "添加失败");
		}
	}

	private String authInfo(String content, Harbor harbor) {
		String dockerconfigjson = null;
		try {
			Encryptor encryptor = new AESEncrptor();
			String registryPassword = encryptor.decrypt(harbor.getPassword(), null);
			String basicAuth = new String(
					Base64.encodeBase64((harbor.getUsername() + ":" + registryPassword).getBytes()));
			content = content.replaceAll("\r", "");
			content = content.replaceAll("        ", "\t");
			if (content.contains("harbor_server_ip")) {
				content = content.replaceAll("harbor_server_ip", harbor.getServerIp());
			}
			if (content.contains("user_auth")) {
				content = content.replaceAll("user_auth", basicAuth);
			}
			dockerconfigjson = new String(Base64.encodeBase64(content.getBytes("UTF-8")), "UTF-8");
			logger.info("dockerconfigjson : " + dockerconfigjson);
		} catch (Exception e) {
			logger.error("认证信息异常:" + e.getMessage());
		}
		return dockerconfigjson;
	}

	@Override
	public BocloudResult modify(KubeSecret service, RequestContext context) {
		String path = KubeSecret.class.getSimpleName() + "_" + service.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			return new BocloudResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify service fail:", e);
			return new BocloudResult(false, "修改失败");
		}
	}

	@Override
	public BocloudResult remove(Long id, RequestContext context) {
		String path = KubeService.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			KubeSecret kubeSecret = kubeSecretRepository.query(id);
			if (null == kubeSecret) {
				return new BocloudResult(false, "数据不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(kubeSecret.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			SecretModel model = new SecretModel();
			model.setName(kubeSecret.getName());
			model.setNamespace(kubeSecret.getNamespace());
			BocloudResult bocloudResult = secretDriver.remove(model, vendor.getUuid());
			if (bocloudResult.isFailed()) {
				return bocloudResult;
			}
			kubeSecretRepository.remove(id, context.getTarget());
			return new BocloudResult(true, "删除成功");
		} catch (Exception e) {
			logger.error("Remove service error:", e);
			return new BocloudResult(false, "删除失败");
		}
	}

	@Override
	public BocloudResult detail(Long id) {
		try {
			KubeSecret kubeSecret = this.kubeSecretRepository.query(id);
			if (null == kubeSecret) {
				return new BocloudResult(false, "数据不存在");
			}
			return new BocloudResult(true, kubeSecret, "查询详情成功");
		} catch (Exception e) {
			logger.error("Get service error：", e);
			return new BocloudResult(false, "查询详情失败");
		}
	}

	@Override
	public BocloudResult apply(String params, RequestContext context) {
		try {
			return new BocloudResult(true, "任务已下发...正在执行！");
		} catch (Exception e) {
			logger.error("Get service error：", e);
			return new BocloudResult(false, e.getMessage());
		}
	}

}
