package com.chenyang.nse.bussiness.service.core.impl;

import com.chenyang.nse.bussiness.dao.PageInfo;
import com.chenyang.nse.bussiness.dao.table.core.TCoreDatasystemDao;
import com.chenyang.nse.bussiness.dao.table.core.controlled.ControlledAssetDao;
import com.chenyang.nse.bussiness.dao.table.core.controlled.TCoreAssetAreaDao;
import com.chenyang.nse.bussiness.dao.table.core.controlled.TCoreAssetRuleDao;
import com.chenyang.nse.bussiness.dao.table.core.dataproject.TCoreDataAreaDao;
import com.chenyang.nse.bussiness.dao.table.core.rule.app.AppDataRuleDao;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreAssetArea;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreAssetRule;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreControlledAsset;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.orm.table.core.dataproject.TCoreDataArea;
import com.chenyang.nse.bussiness.entity.orm.table.core.rule.app.AppDataRule;
import com.chenyang.nse.bussiness.entity.vo.ControlledAssertVO;
import com.chenyang.nse.bussiness.service.core.ControlledAssetService;
import com.chenyang.nse.bussiness.tools.login.CommonUtils;
import com.chenyang.nse.bussiness.tools.string.StringTool;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

@Service
@Repository
@EnableAsync
@Transactional
public class ControlledAssetServiceImpl implements ControlledAssetService {
   @Autowired
   private TCoreDataAreaDao tCoreDataAreaDao;
   @Autowired
   private AppDataRuleDao appDataRuleDao;
   @Autowired
   private TCoreAssetRuleDao assetRuleDao;
   @Autowired
   private ControlledAssetDao controlledAssetDao;
   @Autowired
   private TCoreAssetAreaDao assetAreaDao;
   @Autowired
   private TCoreDatasystemDao datasystemDao;

   public List<ControlledAssertVO> queryControlledAsset(PageInfo pageInfo, Map<String, String> params) {
      String name = "";
      if (null != params && null != params.get("name")) {
         name = (String)params.get("name");
      }

      Criterion criterion1 = Restrictions.like("name", name, MatchMode.ANYWHERE).ignoreCase();
      String business = "";
      if (null != params && null != params.get("business")) {
         business = (String)params.get("business");
      }

      Criterion criterion2 = Restrictions.like("business", business, MatchMode.ANYWHERE).ignoreCase();
      String note = "";
      if (null != params && null != params.get("note")) {
         note = (String)params.get("note");
      }

      Criterion criterion3 = Restrictions.like("note", note, MatchMode.ANYWHERE).ignoreCase();
      String type = "";
      Criterion criterion4;
      if (null != params && null != params.get("type")) {
         type = (String)params.get("type");
         criterion4 = Restrictions.eq("type", type).ignoreCase();
      } else {
         criterion4 = Restrictions.like("type", type, MatchMode.ANYWHERE).ignoreCase();
      }

      List<TCoreControlledAsset> controlledAssetlist = this.controlledAssetDao.queryByPageInfo(pageInfo, Order.desc("createtime"), new Criterion[]{criterion1, criterion2, criterion3, criterion4});
      List<Map<String, Object>> area2ruleList = this.controlledAssetDao.queryAreaNum2RuleNum();
      List<ControlledAssertVO> mergeList = new ArrayList();

      for(int i = 0; i < controlledAssetlist.size(); ++i) {
         ControlledAssertVO assertVO = new ControlledAssertVO();
         BeanUtils.copyProperties(controlledAssetlist.get(i), assertVO);

         for(int j = 0; j < area2ruleList.size(); ++j) {
            if (assertVO.getId().equals(((Map)area2ruleList.get(j)).get("id"))) {
               assertVO.setAreanum((BigInteger)((Map)area2ruleList.get(j)).get("areanum"));
               assertVO.setRulenum((BigInteger)((Map)area2ruleList.get(j)).get("rulenum"));
            }
         }

         mergeList.add(assertVO);
      }

      return mergeList;
   }

   public ControlledAssertVO initControlledAsset(String id) {
      ControlledAssertVO assertVO = new ControlledAssertVO();
      List<ControlledAssertVO> ControlledAssertList = this.controlledAssetDao.queryAssertbyId(id);
      if (!ObjectUtils.isEmpty(ControlledAssertList)) {
         assertVO = (ControlledAssertVO)ControlledAssertList.get(0);
         List<TCoreDataArea> dataAreaList = this.tCoreDataAreaDao.queryByAssetId(id);
         assertVO.setDataAreaList(dataAreaList);
         List<AppDataRule> dataRuleList = this.appDataRuleDao.queryByAssetId(id);
         assertVO.setDataRuleList(dataRuleList);
      }

      return assertVO;
   }

   public TCoreControlledAsset queryByName(String username) {
      return this.controlledAssetDao.queryByName(username);
   }

   public TCoreControlledAsset queryByDatasourceid(String datasourceid) {
      return this.controlledAssetDao.queryByDatasourceid(datasourceid);
   }

   @Transactional
   public void addControlledAsset(ControlledAssertVO controlledAssertVO, HttpServletRequest request) {
      TCoreControlledAsset controlledAsset = new TCoreControlledAsset();
      BeanUtils.copyProperties(controlledAssertVO, controlledAsset);
      List<TCoreDataArea> dataAreaList = controlledAssertVO.getDataAreaList();
      List<AppDataRule> appRuleList = controlledAssertVO.getDataRuleList();
      String username = CommonUtils.loginUsername();
      TCoreDatasystem datasystem = (TCoreDatasystem)this.datasystemDao.get(controlledAssertVO.getDatasourceid());
      controlledAsset.setDatasourcename(datasystem.getSysname());
      controlledAsset.setDbtype(datasystem.getDbtype());
      if (StringUtils.isBlank(controlledAsset.getId())) {
         controlledAsset.setCreateuser(username);
         controlledAsset.setCreatetime(new Date());
         controlledAsset.setFlag("0");
         controlledAsset.setId(StringTool.getTablePrimaryKey());
         this.controlledAssetDao.save(controlledAsset);
         this.saveAreas(dataAreaList, controlledAsset, username);
         this.saveRules(appRuleList, controlledAsset, username);
         controlledAssertVO.setId(controlledAsset.getId());
      } else {
         TCoreControlledAsset tCoreControlledAsset = (TCoreControlledAsset)this.controlledAssetDao.queryUnique(new Criterion[]{Restrictions.eq("id", controlledAsset.getId())});
         tCoreControlledAsset.setBusiness(controlledAsset.getBusiness());
         tCoreControlledAsset.setName(controlledAsset.getName());
         tCoreControlledAsset.setDatasourceid(controlledAsset.getDatasourceid());
         tCoreControlledAsset.setNote(StringUtils.isBlank(controlledAsset.getNote()) ? "" : controlledAsset.getNote());
         tCoreControlledAsset.setFlag("0");
         tCoreControlledAsset.setUpdateuser(username);
         tCoreControlledAsset.setUpdatetime(new Date());
         this.controlledAssetDao.saveOrUpdate(tCoreControlledAsset);
         this.deleteAssetArea(controlledAsset.getId());
         this.saveAreas(dataAreaList, controlledAsset, username);
         this.deleteAssetRule(controlledAsset.getId());
         this.saveRules(appRuleList, controlledAsset, username);
      }

   }

   public void deleteAssetArea(String assetid) {
      Criterion croleid = Restrictions.in("assetid", new Object[]{assetid});
      this.assetAreaDao.remove(new Criterion[]{croleid});
   }

   public void deleteAssetRule(String assetid) {
      Criterion croleid = Restrictions.in("assetid", new Object[]{assetid});
      this.assetRuleDao.remove(new Criterion[]{croleid});
   }

   private void saveAreas(List<TCoreDataArea> dataAreaList, TCoreControlledAsset controlledAsset, String username) {
      if (!ObjectUtils.isEmpty(dataAreaList)) {
         dataAreaList.forEach((item) -> {
            TCoreAssetArea baseUserrole = new TCoreAssetArea();
            baseUserrole.setAreaid(item.getId());
            baseUserrole.setAssetid(controlledAsset.getId());
            baseUserrole.setCreateuser(username);
            baseUserrole.setCreatetime(new Date());
            baseUserrole.setFlag("0");
            baseUserrole.setId(StringTool.getTablePrimaryKey());
            this.assetAreaDao.save(baseUserrole);
         });
      }

   }

   private void saveRules(List<AppDataRule> appDataRuleList, TCoreControlledAsset controlledAsset, String username) {
      if (!ObjectUtils.isEmpty(appDataRuleList)) {
         appDataRuleList.forEach((item) -> {
            TCoreAssetRule assetRule = new TCoreAssetRule();
            assetRule.setRuleid(item.getId());
            assetRule.setAssetid(controlledAsset.getId());
            assetRule.setCreateuser(username);
            assetRule.setCreatetime(new Date());
            assetRule.setFlag("0");
            assetRule.setId(StringTool.getTablePrimaryKey());
            this.assetRuleDao.save(assetRule);
         });
      }

   }

   @Transactional
   public void remove(String id) {
      this.controlledAssetDao.removeById(id);
   }

   @Transactional
   public void deleteAreaByAssetid(String assetid) {
      Criterion croleid = Restrictions.eq("assetid", assetid);
      List<TCoreAssetArea> list = this.assetAreaDao.queryAll(new Criterion[]{croleid});
      this.assetAreaDao.remove(list);
   }

   @Transactional
   public void deleteRuleByAssetid(String assetid) {
      Criterion croleid = Restrictions.eq("assetid", assetid);
      List<TCoreAssetRule> list = this.assetRuleDao.queryAll(new Criterion[]{croleid});
      this.assetRuleDao.remove(list);
   }
}
