package cn.com.qmth.stmms.biz.basic.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.com.qmth.stmms.biz.basic.bean.RoleInfoQuery;
import cn.com.qmth.stmms.biz.basic.bean.RolePrivilegeDomain;
import cn.com.qmth.stmms.biz.basic.bean.RolePrivilegeVo;
import cn.com.qmth.stmms.biz.basic.dao.RoleInfoDao;
import cn.com.qmth.stmms.biz.basic.dao.RolePrivilegeDao;
import cn.com.qmth.stmms.biz.basic.model.RoleInfo;
import cn.com.qmth.stmms.biz.basic.model.RolePrivilege;
import cn.com.qmth.stmms.biz.basic.service.RolePrivilegeService;
import cn.com.qmth.stmms.biz.common.BaseQueryService;
import cn.com.qmth.stmms.common.enums.Role;

@Service("rolePrivilegeService")
public class RolePrivilegeServiceImpl extends BaseQueryService<RolePrivilege> implements RolePrivilegeService {
	private static Map<String, Set<String>> privilegeCodes = new ConcurrentHashMap<>();
	private static Object lock = new Object();
	@Autowired
	private RolePrivilegeDao rolePrivilegeDao;
	
	@Autowired
	private RoleInfoDao roleInfoDao;

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	public Set<String> getRoleCodes(Integer schoolId, Role role) {
		String key = schoolId + "-" + role.name();
		Set<String> set = privilegeCodes.get(key);
		if (set == null) {
			synchronized (lock) {
				set = privilegeCodes.get(key);
				if (set == null) {
					set = new HashSet<>();
					List<RolePrivilege> list = rolePrivilegeDao.findBySchoolIdAndRoleCodeAndEnable(schoolId, role,
							true);
					if (list != null) {
						for (RolePrivilege r : list) {
							set.add(r.getPrivilegeCode());
						}
					}
					privilegeCodes.put(key, set);
				}
			}
		}
		return set;
	}
	
	
	@SuppressWarnings("unchecked")
	@Override
	public List<RolePrivilegeVo> findByQuery(RoleInfoQuery req) {
		StringBuilder sql = new StringBuilder();
		sql.append(" select p.name,p.code,p.parent_code parentCode,t.enable ");
		sql.append(" from b_role_privilege t left join b_privilege p on t.privilege_code=p.code where t.school_id=" 
		+ req.getSchoolId()+" and t.role_code='"+req.getRole()+"'");
		sql.append(" order by p.level,p.seq ");
		Query query = entityManager.createNativeQuery(sql.toString());
		query.unwrap(SQLQuery.class).setResultTransformer(Transformers.aliasToBean(RolePrivilegeVo.class));
		List<RolePrivilegeVo> ret = query.getResultList();
		return ret;
	}

	@Transactional
	@Override
	public void save(RolePrivilegeDomain domain) {
		Role role=Role.valueOf(domain.getRole());
		rolePrivilegeDao.disable(domain.getSchoolId(),role);
		if(StringUtils.isNotBlank(domain.getSelectPrivileges())) {
			List<String> list = Arrays.asList(domain.getSelectPrivileges().split(",") );
			rolePrivilegeDao.enable(domain.getSchoolId(),role,list);
		}
		RoleInfo ri=roleInfoDao.findBySchoolIdAndCode(domain.getSchoolId(),role);
		ri.setUpdateTime(new Date());
		ri.setUpdaterId(domain.getUserId());
		roleInfoDao.save(ri);
		String key = domain.getSchoolId() + "-" + role.name();
		privilegeCodes.remove(key);
	}
}
