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

import com.chenyang.nse.bussiness.dao.core.SensitiveLevelDao;
import com.chenyang.nse.bussiness.dao.table.core.TCoreSensitiveLevelDao;
import com.chenyang.nse.bussiness.dao.table.core.fieldscope.TCoreFieldSensitiveDao;
import com.chenyang.nse.bussiness.dao.table.core.scopeproject.TProAttributeGroupDao;
import com.chenyang.nse.bussiness.dao.table.core.scopeproject.TProEditionScopeDao;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreSensitiveLevel;
import com.chenyang.nse.bussiness.entity.orm.table.core.scopeproject.TProAttributeGroup;
import com.chenyang.nse.bussiness.entity.orm.table.core.scopeproject.TProEditionScope;
import com.chenyang.nse.bussiness.entity.vo.datascope.EditionProjectVO;
import com.chenyang.nse.bussiness.entity.vo.datascope.SensitivelevelVO;
import com.chenyang.nse.bussiness.service.core.SensitiveLevelService;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class SensitiveLevelServiceImpl implements SensitiveLevelService {
   @Autowired
   private TCoreSensitiveLevelDao tCoreSensitiveLevelDao;
   @Autowired
   private TCoreFieldSensitiveDao tCoreFieldSensitiveDao;
   @Autowired
   private SensitiveLevelDao sensitiveLevelDao;
   @Autowired
   private TProEditionScopeDao tProEditionScopeDao;
   @Autowired
   private TProAttributeGroupDao tProAttributeGroupDao;

   public void save(SensitivelevelVO scope) {
      if (scope.getTid() != null && !"".equals(scope.getTid())) {
         this.sensitiveLevelDao.updateScope(scope);
      } else if (scope.getFa_tid() == null) {
         scope.setTid(UUID.randomUUID().toString().replace("-", ""));
         List<TCoreSensitiveLevel> ll = this.tCoreSensitiveLevelDao.queryAll(new Criterion[]{Restrictions.eq("edition_id", scope.getEdition_id())});
         if (ll.size() > 0) {
            this.sensitiveLevelDao.insertAddFa(scope);
         } else {
            this.sensitiveLevelDao.insertAddZero(scope);
         }
      } else if (this.sensitiveLevelDao.ishavebro(scope).size() > 0) {
         scope.setTid(UUID.randomUUID().toString().replace("-", ""));
         this.sensitiveLevelDao.havebro(scope);
      } else {
         scope.setTid(UUID.randomUUID().toString().replace("-", ""));
         this.sensitiveLevelDao.nothavebro(scope);
      }

      this.sensitiveLevelDao.delRelation(scope);
      String rules = scope.getRules();
      if (rules != null && rules != "") {
         String[] ruleList = rules.split(",");

         for(String rule : ruleList) {
            this.sensitiveLevelDao.insertRelation(scope, rule);
         }
      }

      String idPro = scope.getTid();
      this.saveColumn(scope, idPro);
   }

   public void remove(String id) {
      TCoreSensitiveLevel ds = (TCoreSensitiveLevel)this.tCoreSensitiveLevelDao.queryUnique(new Criterion[]{Restrictions.eq("id", id)});
      List<Map<String, Object>> relatedList = this.tCoreSensitiveLevelDao.relatedfandson(ds.getSensitive_id(), ds.getEdition_id());
      List<String> listname = new ArrayList();

      for(Map<String, Object> a : relatedList) {
         listname.add((String)a.get("id"));
      }

      this.tCoreFieldSensitiveDao.remove(new Criterion[]{Restrictions.in("scope_id", listname)});
      this.sensitiveLevelDao.delselfandson(ds.getSensitive_id(), ds.getEdition_id());

      for(SensitivelevelVO SensitivelevelVO : this.sensitiveLevelDao.findbroandhisson(ds.getSensitive_id(), ds.getFa_tid(), ds.getEdition_id())) {
         if (ds.getFa_tid().equals(SensitivelevelVO.getFa_tid())) {
            this.sensitiveLevelDao.updatebro(SensitivelevelVO.getTid());
         } else {
            this.sensitiveLevelDao.updatebroson(SensitivelevelVO.getTid(), ds.getSensitive_id());
         }
      }

   }

   public List<SensitivelevelVO> getScopeTable(SensitivelevelVO vo) {
      new ArrayList();
      List<SensitivelevelVO> list = this.sensitiveLevelDao.getDataScopeGroup(vo.getEdition_id());
      if (list.size() > 0) {
         list.forEach((l) -> {
            List<TProAttributeGroup> listGroup = this.tProAttributeGroupDao.queryAll(new Criterion[]{Restrictions.eq("group_id", l.getTid())});
            Map<String, String> map = new HashMap();
            listGroup.forEach((lg) -> map.put(lg.getColumnname(), lg.getColumnvalue()));
            l.setColumnsGroups(map);
         });
      }

      List<SensitivelevelVO> trees = this.buildTree(list, "全部");
      return trees;
   }

   private List<SensitivelevelVO> buildTree(List<SensitivelevelVO> list, String parentId) {
      List<SensitivelevelVO> trees = new ArrayList();

      for(SensitivelevelVO entity : list) {
         String menuId = entity.getTid();
         String pid = entity.getFa_tid();
         if (parentId.equals(pid)) {
            List<SensitivelevelVO> menuLists = this.buildTree(list, menuId);
            entity.setChildren(menuLists);
            trees.add(entity);
         }
      }

      return trees;
   }

   public SensitivelevelVO editbyid(String id) {
      TCoreSensitiveLevel result = (TCoreSensitiveLevel)this.tCoreSensitiveLevelDao.queryUnique(new Criterion[]{Restrictions.eq("id", id)});
      if (result != null) {
         String fatid = result.getFa_tid();
         String editionid = result.getEdition_id();
         SensitivelevelVO vo = new SensitivelevelVO();
         if ("全部".equals(fatid)) {
            vo.setFa_name("全部");
         } else {
            String faid = ((TCoreSensitiveLevel)this.tCoreSensitiveLevelDao.queryAll(new Criterion[]{Restrictions.eq("id", id)}).get(0)).getFa_tid();
            vo.setFa_name(((TCoreSensitiveLevel)this.tCoreSensitiveLevelDao.queryAll(new Criterion[]{Restrictions.eq("id", faid), Restrictions.eq("edition_id", editionid)}).get(0)).getSensitive_name());
         }

         List<Map<String, String>> maps = this.sensitiveLevelDao.selectRelation(id);
         String rules = "";
         if (maps != null && !maps.isEmpty()) {
            for(Map<String, String> map : maps) {
               if (rules == "") {
                  rules = rules + (String)map.get("rule");
               } else {
                  rules = rules + "," + (String)map.get("rule");
               }
            }
         }

         vo.setTid(result.getId());
         vo.setText(result.getSensitive_name());
         vo.setId(result.getSensitive_id());
         vo.setFa_tid(result.getFa_tid());
         vo.setNote(result.getNote());
         vo.setEdition_id(result.getEdition_id());
         vo.setOpen_level(result.getOpen_level());
         vo.setScope_according(result.getScope_according());
         vo.setLevel_principle(result.getLevel_principle());
         vo.setCreate_user(result.getCreate_user());
         vo.setCreate_date(result.getCreate_date());
         vo.setRules(rules);
         List<TProAttributeGroup> list = this.tProAttributeGroupDao.queryAll(new Criterion[]{Restrictions.eq("group_id", id)});
         Map<String, String> map = new HashMap();
         list.forEach((l) -> map.put(l.getColumnname(), l.getColumnvalue()));
         vo.setColumnsGroups(map);
         return vo;
      } else {
         return null;
      }
   }

   public List<TProEditionScope> getDataScopeProjectList(String editionEn) {
      List<TProEditionScope> list = this.tProEditionScopeDao.queryAll(new Criterion[]{Restrictions.eq("scope_level", editionEn), Restrictions.eq("enable_type", "1")});
      return list;
   }

   public void saveProject(EditionProjectVO project) {
      try {
         Class clazz = project.getClass();
         TProEditionScope tes = new TProEditionScope();
         String idPro = project.getTid();
         if (idPro != null && !"".equals(idPro)) {
            this.tProEditionScopeDao.remove(new Criterion[]{Restrictions.eq("id", idPro)});
            this.tProAttributeGroupDao.remove(new Criterion[]{Restrictions.eq("group_id", idPro)});
         }

         tes.setEdition_name(project.getEdition_name());
         tes.setScope_level(project.getScope_level());
         tes.setEnable_type("1");
         tes.setNote(project.getNote());
         tes.setCreate_user(project.getCreate_user());
         tes.setCreate_date(new Date());
         this.tProEditionScopeDao.save(tes);

         for(int i = 1; i < 11; ++i) {
            TProAttributeGroup tag = new TProAttributeGroup();
            Field field1 = clazz.getDeclaredField("columnname" + i);
            field1.setAccessible(true);
            String val = (String)field1.get(project);
            if (val == null || "".equals(val)) {
               break;
            }

            Field field2 = clazz.getDeclaredField("columnvalue" + i);
            field2.setAccessible(true);
            String val2 = (String)field2.get(project);
            tag.setId(UUID.randomUUID().toString().replace("-", ""));
            tag.setGroup_id(tes.getId());
            tag.setColumnnum(String.valueOf(i));
            tag.setColumnname(val);
            tag.setColumnvalue(val2);
            this.tProAttributeGroupDao.save(tag);
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   public EditionProjectVO editpeproject(String id) {
      EditionProjectVO vo = new EditionProjectVO();
      TProEditionScope tes = (TProEditionScope)this.tProEditionScopeDao.queryUnique(new Criterion[]{Restrictions.eq("id", id)});
      vo.setTid(id);
      vo.setEdition_name(tes.getEdition_name());
      vo.setNote(tes.getNote());
      vo.setCreate_user(tes.getCreate_user());
      vo.setCreate_date(tes.getCreate_date());
      List<TProAttributeGroup> list = this.tProAttributeGroupDao.queryAll(new Criterion[]{Restrictions.eq("group_id", id)});

      try {
         Class clazz = vo.getClass();

         for(TProAttributeGroup tpag : list) {
            String str1 = "columnname" + tpag.getColumnnum();
            String str2 = "columnvalue" + tpag.getColumnnum();
            Field field1 = clazz.getDeclaredField(str1);
            Field field2 = clazz.getDeclaredField(str2);
            field1.setAccessible(true);
            field2.setAccessible(true);
            field1.set(vo, tpag.getColumnname());
            field2.set(vo, tpag.getColumnvalue());
         }

         String str3 = "columncount";
         Field field3 = clazz.getDeclaredField(str3);
         field3.setAccessible(true);
         field3.set(vo, String.valueOf(list.size()));
      } catch (Exception e) {
         e.printStackTrace();
      }

      return vo;
   }

   public void removepeproject(String id) {
      this.tProEditionScopeDao.removePro(id);
   }

   private void saveColumn(SensitivelevelVO obj, String idPro) {
      try {
         Class clazz = obj.getClass();
         if (idPro != null && !"".equals(idPro)) {
            this.tProAttributeGroupDao.remove(new Criterion[]{Restrictions.eq("group_id", idPro)});
         }

         obj.getColumnsGroups().entrySet().forEach((map) -> {
            TProAttributeGroup tag = new TProAttributeGroup();
            tag.setId(UUID.randomUUID().toString().replace("-", ""));
            tag.setGroup_id(idPro);
            tag.setColumnname((String)map.getKey());
            tag.setColumnvalue((String)map.getValue());
            this.tProAttributeGroupDao.save(tag);
         });
      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   public List<TProEditionScope> geteditionlist() {
      List<TProEditionScope> list = this.tProEditionScopeDao.queryAll(Order.desc("create_date"), new Criterion[]{Restrictions.eq("scope_level", "1"), Restrictions.eq("enable_type", "1")});
      return list;
   }

   public List<TProEditionScope> geteditionlistds(String projectId) {
      List<TProEditionScope> list = this.tProEditionScopeDao.queryAll(Order.desc("create_date"), new Criterion[]{Restrictions.eq("scope_level", "1"), Restrictions.eq("enable_type", "1"), Restrictions.eq("projectid", projectId)});
      return list;
   }

   public String getmaxdatetid(String editionid) {
      String id = "";
      if (editionid != null && !"".equals(editionid)) {
         List<Map<String, Object>> tmax = this.tCoreSensitiveLevelDao.getmaxdatetid(editionid);
         if (!tmax.isEmpty()) {
            id = (String)((Map)tmax.get(0)).get("id");
         }
      }

      return id;
   }

   public Map<String, Object> getSensitiveInfo(String scopeid) {
      Map<String, Object> sensitiveInfo = this.sensitiveLevelDao.getSensitiveInfo(scopeid);
      return sensitiveInfo;
   }

   public void removeByEdition(String editionid) {
      this.tCoreFieldSensitiveDao.remove(new Criterion[]{Restrictions.eq("edition_id", editionid)});
      this.tProAttributeGroupDao.removeAssSensitive(editionid);
      this.tCoreSensitiveLevelDao.remove(new Criterion[]{Restrictions.eq("edition_id", editionid)});
      this.sensitiveLevelDao.delrelationByeditionid(editionid, "3");
   }

   private void saveScopeData(TCoreSensitiveLevel data) {
      this.tCoreSensitiveLevelDao.save(data);
      String fid = data.getId();
      data.getGroups().forEach((g) -> {
         g.setGroup_id(fid);
         this.tProAttributeGroupDao.save(g);
      });
      if (data.getChildrens().size() > 0) {
         data.getChildrens().forEach((c) -> {
            c.setFa_tid(fid);
            this.saveScopeData(c);
         });
      }

   }

   private void saveScopeDataMap(Map<String, TCoreSensitiveLevel> map) {
      TCoreSensitiveLevel all = (TCoreSensitiveLevel)map.get("全部");
      List<TCoreSensitiveLevel> fathers = all.getChildrens();
      fathers.forEach((f) -> this.saveScopeData(f));
   }

   public void saveExcelData(List<List<String>> list, String editionid, String user) throws Exception {
      Map<String, TCoreSensitiveLevel> map = new HashMap();
      map.put("全部", new TCoreSensitiveLevel());
      list.stream().forEach((row) -> {
         String uuid = UUID.randomUUID().toString().replace("-", "");
         TCoreSensitiveLevel tds = new TCoreSensitiveLevel();
         tds.setSensitive_id((String)row.get(0));
         tds.setSensitive_name((String)row.get(1));
         tds.setNote((String)row.get(2));
         tds.setOpen_level(((String)row.get(3)).charAt(0));
         tds.setEdition_id(editionid);
         tds.setCreate_user(user);
         tds.setCreate_date(new Date());
         map.put(row.get(0), tds);
      });
      map.entrySet().forEach((row) -> {
         if (((String)row.getKey()).length() > 3) {
            String fscope = ((TCoreSensitiveLevel)row.getValue()).getSensitive_id().substring(0, ((TCoreSensitiveLevel)row.getValue()).getSensitive_id().length() - 3);
            TCoreSensitiveLevel fdata = (TCoreSensitiveLevel)map.get(fscope);
            List<TCoreSensitiveLevel> childrens = fdata.getChildrens();
            childrens.add(row.getValue());
         } else if (((String)row.getKey()).length() == 3) {
            ((TCoreSensitiveLevel)row.getValue()).setFa_tid("全部");
            ((TCoreSensitiveLevel)map.get("全部")).getChildrens().add(row.getValue());
         }

      });
      this.saveScopeDataMap(map);
   }

   public String checkName(String sensitivename, String editionid) {
      List<TCoreSensitiveLevel> list = this.tCoreSensitiveLevelDao.queryAll(new Criterion[]{Restrictions.eq("sensitive_name", sensitivename), Restrictions.eq("edition_id", editionid)});
      return list.isEmpty() ? "yes" : "no";
   }

   public boolean dataScopeIsExistsByName(String text, String editionid) {
      return this.tCoreSensitiveLevelDao.queryUnique(new Criterion[]{Restrictions.eq("sensitive_name", text), Restrictions.eq("edition_id", editionid)}) != null;
   }

   public char getMaxOpenLevel(String edition_id) {
      return this.sensitiveLevelDao.getMaxOpenLevel(edition_id);
   }

   public void saveReorder(String moveNodeId, String toNodeId, String moveType) {
      TCoreSensitiveLevel moveNode = (TCoreSensitiveLevel)this.sensitiveLevelDao.queryUnique(new Criterion[]{Restrictions.eq("id", moveNodeId)});
      TCoreSensitiveLevel toNode = (TCoreSensitiveLevel)this.sensitiveLevelDao.queryUnique(new Criterion[]{Restrictions.eq("id", toNodeId)});
      char start = '\u0000';
      char end = '\u0000';
      int a = moveNode.getOpen_level() - toNode.getOpen_level();
      if ("before".equalsIgnoreCase(moveType)) {
         if (a > 0) {
            start = toNode.getOpen_level();
            end = moveNode.getOpen_level();
         } else {
            start = moveNode.getOpen_level();
            end = toNode.getOpen_level();
         }

         List<TCoreSensitiveLevel> list = this.sensitiveLevelDao.queryAll(Order.asc("open_level"), new Criterion[]{Restrictions.eq("edition_id", moveNode.getEdition_id()), Restrictions.between("open_level", start, end)});
         if (a > 0) {
            this.sensitiveLevelDao.updateOpenLevelById(moveNode.getId(), toNode.getOpen_level());

            for(int i = 0; i < list.size() - 1; ++i) {
               this.sensitiveLevelDao.updateOpenLevelById(((TCoreSensitiveLevel)list.get(i)).getId(), (char)(((TCoreSensitiveLevel)list.get(i)).getOpen_level() + 1));
            }
         } else {
            this.sensitiveLevelDao.updateOpenLevelById(moveNode.getId(), (char)(toNode.getOpen_level() - 1));

            for(int i = 1; i < list.size() - 1; ++i) {
               this.sensitiveLevelDao.updateOpenLevelById(((TCoreSensitiveLevel)list.get(i)).getId(), (char)(((TCoreSensitiveLevel)list.get(i)).getOpen_level() - 1));
            }
         }
      } else if ("after".equalsIgnoreCase(moveType)) {
         if (a > 0) {
            start = toNode.getOpen_level();
            end = moveNode.getOpen_level();
         } else {
            start = moveNode.getOpen_level();
            end = toNode.getOpen_level();
         }

         List<TCoreSensitiveLevel> list = this.sensitiveLevelDao.queryAll(Order.asc("open_level"), new Criterion[]{Restrictions.eq("edition_id", moveNode.getEdition_id()), Restrictions.between("open_level", start, end)});
         if (a > 0) {
            this.sensitiveLevelDao.updateOpenLevelById(moveNode.getId(), (char)(toNode.getOpen_level() + 1));

            for(int i = 1; i < list.size() - 1; ++i) {
               this.sensitiveLevelDao.updateOpenLevelById(((TCoreSensitiveLevel)list.get(i)).getId(), (char)(((TCoreSensitiveLevel)list.get(i)).getOpen_level() + 1));
            }
         } else {
            this.sensitiveLevelDao.updateOpenLevelById(moveNode.getId(), toNode.getOpen_level());

            for(int i = 1; i < list.size(); ++i) {
               this.sensitiveLevelDao.updateOpenLevelById(((TCoreSensitiveLevel)list.get(i)).getId(), (char)(((TCoreSensitiveLevel)list.get(i)).getOpen_level() - 1));
            }
         }
      }

   }
}
