package com.bocloud.ims.repository.resource;

import com.bocloud.cmp.entity.enums.BocloudStatus;
import com.bocloud.common.model.Pager;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.MapTools;
import com.bocloud.database.core.intf.impl.BasicGenericDao;
import com.bocloud.database.utils.QueryBuilder;
import com.bocloud.ims.entity.resource.ResourceAlarm;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;

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

@Service("resourceAlarmRepository")
public class ResourceAlarmRepository extends BasicGenericDao<ResourceAlarm, Long> {

	public ResourceAlarmRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate) {
		super(jdbcTemplate, npJdbcTemplate);
	}

	public List<ResourceAlarm> list(int page, int rows, List<Param> params, Map<String, String> sorter)
			throws Exception {
		String sql = "select a.*,b.name vendor_name from resource_alarm a left join cloud_vendor b on a.vendor_id = b.id where a.is_deleted = 0";
		sql = QueryBuilder.buildRaw(sql, new Pager(page, rows, params, sorter), "a");
		Map<String, Object> paramMap = QueryBuilder.getParam(params);
		return this.list(ResourceAlarm.class, sql, paramMap);
	}

	public List<SimpleBean> list(List<Param> params, Map<String, String> sorter) throws Exception {
		String sql = "select a.id,a.name from resource_alarm a where a.is_deleted = 0";
		sql = QueryBuilder.build(sql, new Pager(1, Integer.MAX_VALUE, params, sorter), "a");
		Map<String, Object> paramMap = QueryBuilder.getParam(params);
		List<ResourceAlarm> alarms = this.list(ResourceAlarm.class, sql, paramMap);
		List<SimpleBean> beans = new ArrayList<>();
		for (ResourceAlarm alarm : alarms) {
			beans.add(new SimpleBean(alarm.getId(), alarm.getName()));
		}
		return beans;
	}

	public int count(List<Param> params) throws Exception {
		String sql = "select count(1) from resource_alarm a where a.is_deleted = 0";
		sql = QueryBuilder.buildRaw(sql, params, null, "a");
		Map<String, Object> paramMap = QueryBuilder.getParam(params);
		return this.countQuery(sql, paramMap).intValue();
	}

	public boolean removeByVid(Long vendorId, Long userId) throws Exception {
		String sql = "update resource_alarm set is_deleted = 1, gmt_modify = :gmtModify, mender_id = :menderId where vendor_id = :vendorId";
		Map<String, Object> params = MapTools.simpleMap(Common.VENDORID, vendorId);
		params.put("gmtModify", new Date());
		params.put("menderId", userId);
		return this.execute(sql, params) > 0;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see com.bocloud.cmp.Repository.AlarmRepository#deleteByVid(java.lang.Long)
	 */

	public boolean deleteByVendor(Long vendorId) throws Exception {
		String sql = "delete from resource_alarm where vendor_id = :vendorId";
		Map<String, Object> params = MapTools.simpleMap(Common.VENDORID, vendorId);
		return this.execute(sql, params) > 0;
	}

	public List<ResourceAlarm> listByVendor(Long vendorId) throws Exception {
		String sql = "select a.* from resource_alarm a where a.is_deleted = 0 and a.vendor_id = :vendorId";
		Map<String, Object> params = MapTools.simpleMap(Common.VENDORID, vendorId);
		return this.list(ResourceAlarm.class, sql, params);
	}

	public boolean delete(Long id, Long userId) throws Exception {
		String sql = "update resource_alarm set is_deleted = 1, gmt_modify = :gmtModify, mender_id = :menderId where id = :id";
		Map<String, Object> params = MapTools.simpleMap(Common.ID, id);
		params.put("gmtModify", new Date());
		params.put("menderId", userId);
		return this.execute(sql, params) > 0;
	}

	public ResourceAlarm query(Long id) throws Exception {
		String sql = "select a.*,b.name vendor_name from resource_alarm a left join cloud_vendor b on a.vendor_id = b.id where a.is_deleted = 0 and a.id = :id";
		Map<String, Object> params = MapTools.simpleMap(Common.ID, id);
		List<ResourceAlarm> list = this.list(ResourceAlarm.class, sql, params);
		if (list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	public List<ResourceAlarm> list(int page, int rows, List<Param> params, Map<String, String> sorter, String type)
			throws Exception {
		String sql = "select a.*,b.name vendor_name from resource_alarm a,cloud_vendor b where a.is_deleted = 0 and a.vendor_id = b.id";
		if (!StringUtils.isEmpty(type)) {
			sql += " and b.type = '" + type + "'";
		}
		sql = QueryBuilder.buildRaw(sql, new Pager(page, rows, params, sorter), "a");
		Map<String, Object> paramMap = QueryBuilder.getParam(params);
		return this.list(ResourceAlarm.class, sql, paramMap);
	}

	public int count(List<Param> params, String type) throws Exception {
		String sql = "select count(1) from resource_alarm a,cloud_vendor b where a.is_deleted = 0 and a.vendor_id = b.id";
		if (!StringUtils.isEmpty(type)) {
			sql += " and b.type = '" + type + "'";
		}
		sql = QueryBuilder.buildRaw(sql, params, null, "a");
		Map<String, Object> paramMap = QueryBuilder.getParam(params);
		return this.countQuery(sql, paramMap).intValue();
	}

	public List<ResourceAlarm> listAll() throws Exception {
		String sql = "select a.*,b.name vendor_name from resource_alarm a,cloud_vendor b where a.is_deleted = 0 and a.vendor_id = b.id";
		return this.list(ResourceAlarm.class, sql);
	}

	public void create(ResourceAlarm alarm) throws Exception {
		this.save(alarm);
	}

	public List<ResourceAlarm> unconfirms(boolean existRuleId) throws Exception {
		String sql = "select * from resource_alarm a where a.is_deleted = 0 and a.level != 'OK' and a.status = :status";
		Map<String, Object> params = MapTools.simpleMap("status", BocloudStatus.Alarm.UNCONFIRMED.name());
		if (existRuleId) {
			sql += " and a.rule_id is not null and a.rule_id != 0 ";
		} else {
			sql += " (and a.rule_id is null or a.rule_id = 0) ";
		}
		return this.list(ResourceAlarm.class, sql, params);
	}

	public boolean updateStatus(Long id, Long userId, String status, String confirmer) throws Exception {
		String sql = "";
		Map<String, Object> paramMap = MapTools.simpleMap("id", id);
		paramMap.put("status", status);
		paramMap.put("menderId", userId);
		paramMap.put("gmtModify", new Date());
		if (BocloudStatus.Alarm.CONFIRMED.name().equals(status)) {
			sql += "update resource_alarm a set a.status = :status,a.mender_id = :menderId,a.gmt_modify = :gmtModify,a.confirmer = :confirmer,a.gmt_confirm = :gmtConfirm where a.id = :id";
			paramMap.put("confirmer", confirmer);
			paramMap.put("gmtConfirm", new Date());
		} else if (BocloudStatus.Alarm.SOLVED.name().equals(status)) {
			sql += "update resource_alarm a set a.status = :status,a.mender_id = :menderId,a.gmt_modify = :gmtModify where a.id = :id";
		}
		return this.execute(sql, paramMap) > 0;
	}

	public boolean solve(Long id, Long userId, String solver, String dealResult) throws Exception {
		String sql = "update resource_alarm a set a.status = :status,a.solver = :solver,a.gmt_solve = :gmtSolve,deal_result = :dealResult,a.mender_id = :menderId,a.gmt_modify = :gmtModify where a.id = :id";
		Map<String, Object> params = MapTools.simpleMap("id", id);
		params.put("solver", solver);
		params.put("gmtSolve", new Date());
		params.put("dealResult", dealResult);
		params.put("menderId", userId);
		params.put("gmtModify", new Date());
		params.put("status", BocloudStatus.Alarm.SOLVED.name());
		return this.execute(sql, params) > 0;
	}

	public ResourceAlarm queryAlarmMain(String level, Long ruleId, String target) throws Exception {
		String sql = "select a.id from resource_alarm a where a.level = :level and a.rule_id = :ruleId and a.target = :target and a.status != 'SOLVED' and a.is_deleted = 0";
		Map<String, Object> paramMap = MapTools.simpleMap("level", level);
		paramMap.put("ruleId", ruleId);
		paramMap.put("target", target);
		List<ResourceAlarm> list = this.list(ResourceAlarm.class, sql, paramMap);
		if (list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	public List<ResourceAlarm> unSolves() throws Exception {
		String sql = "select a.* from resource_alarm a where a.rule_id is not null and a.status != 'SOLVED' and a.is_deleted = 0";
		return this.list(ResourceAlarm.class, sql);
	}

	public ResourceAlarm getAlarm(String name, String level, String type, Long target, String alarmVal)
			throws Exception {
		String sql = "select a.* from resource_alarm a where a.is_deleted = 0 and a.event_alarm = 1 and a.status = 'UNCONFIRMED' and a.name = :name and a.level = :level and a.type = :type and a.target = :target and a.alarm_val = :alarmVal ";
		Map<String, Object> params = MapTools.simpleMap("name", name);
		params.put("level", level);
		params.put("type", type);
		params.put("target", target);
		params.put("alarmVal", alarmVal);
		List<ResourceAlarm> list = this.list(ResourceAlarm.class, sql, params);
		if (list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	public boolean removeByTarget(String target, String type) throws Exception {
		String sql = "update resource_alarm set is_deleted = 1 where is_deleted = 0 and target = :target and type = :type";
		Map<String, Object> paramMap = MapTools.simpleMap("target", target);
		paramMap.put("type", type);
		return this.execute(sql, paramMap) > 0;
	}

	public boolean addAlarm(String name, String level, String type, Long target, String alarmVal) throws Exception {
		ResourceAlarm alarm = getAlarm(name, level, type, target, alarmVal);
		if (null != alarm) {
			return false;
		}

		alarm = new ResourceAlarm(level, type, target, alarmVal, new Date(), true);
		alarm.setCreatorId(1L);
		alarm.setGmtCreate(new Date());
		alarm.setStatus("UNCONFIRMED");
		alarm.setDeleted(false);
		alarm.setName(name);
		save(alarm);

		return true;
	}

	public List<ResourceAlarm> listVendorAlarm() throws Exception {
		String sql = "select a.* from resource_alarm a where a.is_deleted = 0 and a.vendor_id is not null";
		return this.list(ResourceAlarm.class, sql);
	}
}
