package net.wicp.tams.duckula.ops.pages.cas;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.lang3.StringUtils;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.util.TextStreamResponse;
import org.w3c.dom.Document;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import net.wicp.tams.app.duckula.controller.bean.constant.ResAuthType;
import net.wicp.tams.app.duckula.controller.bean.models.SysResource;
import net.wicp.tams.app.duckula.controller.dao.SysResourceMapper;
import net.wicp.tams.app.duckula.controller.service.ContextInit;
import net.wicp.tams.app.duckula.controller.service.cas.IMenuService;
import net.wicp.tams.common.Result;
import net.wicp.tams.common.apiext.CollectionUtil;
import net.wicp.tams.common.apiext.StringUtil;
import net.wicp.tams.common.apiext.json.EasyUiAssist;
import net.wicp.tams.common.apiext.json.easyuibean.EasyUINode;
import net.wicp.tams.common.connector.XmlUtil;
import net.wicp.tams.common.constant.dic.YesOrNo;
import net.wicp.tams.component.tools.TapestryAssist;
import net.wicp.tams.duckula.ops.beans.SessionBean;
import net.wicp.tams.duckula.ops.pages.ParentPageBean;

@Import(stack = "easyuistack")
public class ResManager extends ParentPageBean<SysResource> {
	@Inject
	private IMenuService menuService;

	@Inject
	private SysResourceMapper sysResourceMapper;

	@SessionState
	private SessionBean sessionBean;

	public TextStreamResponse onQueryMenu() throws Exception {
		List<EasyUINode> roots = menuService.findAllModuleMenu(I18NConvert, true, true, sessionBean.isSuperUser());
		String retstr = EasyUiAssist.getTreeFromList(roots);
		return retStream(retstr);
	}

	public TextStreamResponse onSaveRes() {
		JSONObject params = TapestryAssist.packParams(request, false);
		String id = params.getString("id");
		String parentId = params.getString("parentId");
		String icon = params.getString("icon");
		String resLevel = params.getString("resLevel");
		String caResType = params.getString("caResType");

		String showOrder = params.getString("showOrder");
		String resCode = params.getString("resCode");
		String resName = params.getString("resName");
		String resValue = params.getString("resValue");
		String isEdit = params.getString("isEdit");
		String remark = params.getString("remark");
		String bound1 = params.getString("bound1");// app
		String bound2 = params.getString("bound2");// 是否菜单
		if (StringUtil.isNull(bound1)) {// bound1如果为空
			bound1 = null;
			if (Integer.parseInt(resLevel) == 2) {
				bound1 = parentId;
			} else if (Integer.parseInt(resLevel) == 3) {// 需要查一下数据库
				SysResource parentObj = (SysResource) sysResourceMapper.selectById(Long.parseLong(parentId));
				bound1 = String.valueOf(parentObj.getParentId());
			}
		}
		SysResource rs = new SysResource();
		if (StringUtils.isNotBlank(id)) {
			rs.setId(Long.parseLong(id));
		}

		rs.setResCode(resCode);
		rs.setResName(resName);
		rs.setResValue(resValue);
		rs.setResType(caResType);
		rs.setIcon(icon);
		rs.setResLevel(Integer.parseInt(resLevel));
		rs.setIsEdit(isEdit);
		rs.setParentId(Long.parseLong(parentId));

		rs.setShowOrder(Long.parseLong(showOrder));
		rs.setRemark(remark);
		rs.setBound1(bound1);
		rs.setBound2(bound2);
		if (rs.getId() == null) {
			sysResourceMapper.insert(rs);
		} else {
			sysResourceMapper.updateById(rs);
		}
		Result res = Result.getSuc();
		com.alibaba.fastjson.JSONObject retobj = res.retJsonObj();
		retobj.put("id", rs.getId());

		JSONObject attributes = new JSONObject("resCode", resCode, "resName", resName, "resValue", resValue, "isEdit",
				isEdit, "remark", remark, "bound1", bound1, "bound2", bound2);
		retobj.put("attributes", attributes);
		retobj.put("index", Integer.parseInt(showOrder));
		retobj.put("text", I18NConvert.getStr(resName));
		return retStream(retobj.toString());
	}

	/****
	 * 删除Res
	 *
	 * @return
	 */
	public TextStreamResponse onDelRes() {
		String id = request.getParameter("id");
		sysResourceMapper.deleteById(Long.parseLong(id));
		return TapestryAssist.getTextStreamResponse(Result.getSuc());
	}

	/**
	 * 更新菜单列表，当前的方案是：扫描page目录下的TML文件及目录结构
	 *
	 * @return
	 */
	public TextStreamResponse onSyncRes() {
		QueryWrapper<SysResource> queryWrapper = new QueryWrapper<SysResource>();
		queryWrapper.eq("parent_id", 1);
		List<SysResource> selectList = sysResourceMapper.selectList(queryWrapper);
		Set<Long> mods = CollectionUtil.getColSetFromObj(selectList, "id");

		Result ret = Result.getSuc();
		try {
			Collection<File> files = FileUtils.listFiles(new File(ContextInit.pagePath), fileFilter, dirFilter);

			final List<SysResource> hasResList = new ArrayList<SysResource>();
			for (File file : files) {
				SysResource res = new SysResource();
				res.setResType(ResAuthType.URL.name());

				String path = file.getPath();
				int beginIndex = path.indexOf("pages" + File.separator);
				int endIndex = path.indexOf(".tml");
				path = path.substring(beginIndex + 5, endIndex);
				res.setResValue(path.replaceAll("\\" + File.separator, "/"));// 资源值
				res.setResCode(path.replaceAll("\\" + File.separator, "_"));
				String fileContext = FileUtils.readFileToString(file, "utf-8");
				int beginTitle = fileContext.indexOf("<title");
				int endTitle = fileContext.indexOf("</title>");

				boolean isMenu = false;
				String value = "";
				long module = -1;
				if (beginTitle >= 0 && endTitle > beginTitle) {
					try {
						Document doc = XmlUtil.parserDocment(fileContext.substring(beginTitle, endTitle + 8));
						if (doc != null && doc.getFirstChild() != null && doc.getFirstChild().getFirstChild() != null) {
							value = doc.getFirstChild().getFirstChild().getNodeValue();
							String isMenuStr = findAttrByName(doc, "isMenu");
							isMenu = Boolean.parseBoolean(isMenuStr);

							String moduleStr = findAttrByName(doc, "module");// 它可以没有
							try {
								module = Long.parseLong(moduleStr);
								if (!mods.contains(module)) {// 页面设置的模块不在数据库中
									module = -1;
								}
							} catch (Exception e) {
							}

						}
					} catch (Exception e) {
					}
				}
				if (!isMenu) {// 是菜单
					continue;
				}

				if (module > 0) {
					res.setParentId(module);
				}

				value = value.replace("$", "").replace("{", "").replace("}", "").replace("message:", "");
				res.setResName(StringUtils.isEmpty(value) ? file.getName() : value);// 资源名称，国际化的key值,如果没拿到key值，就用文件名代替
				hasResList.add(res);
			}
			final List<SysResource> dbResList = menuService.findSyncRes();// 查找数据库已有的菜单
			Set<Object> synValueList = CollectionUtil.getColSetFromObj(hasResList, "resValue");
			// 数据库中有的，但已不存在此页面的，需要删除
			List<SysResource> deleteList = (List<SysResource>) CollectionUtils.select(dbResList, new Predicate() {
				@Override
				public boolean evaluate(Object object) {
					SysResource temp = (SysResource) object;
					return !synValueList.contains(temp.getResValue());
				}
			});

			for (SysResource ca_Resource : deleteList) {
				sysResourceMapper.deleteById(ca_Resource.getId());
			}

			// dbResList 剩余的集合、更新
			List<SysResource> updateList = (List<SysResource>) CollectionUtils.select(dbResList, new Predicate() {
				@Override
				public boolean evaluate(Object object) {
					SysResource tempobj = (SysResource) object;
					return synValueList.contains(tempobj.getResValue()) && "yes".equals(tempobj.getIsEdit());
				}
			});
			for (SysResource ca_Resource : updateList) {
				ca_Resource.setIsEdit(YesOrNo.yes.name());
				ca_Resource.setRemark("系统自动同步");
				ca_Resource.setIsSync(YesOrNo.yes.name());
				ca_Resource.setBound2(YesOrNo.yes.name());
				sysResourceMapper.updateByPrimaryKeySelective(ca_Resource);
			}
			Set<Object> dbValueList = CollectionUtil.getColSetFromObj(dbResList, "resValue");
			// 数据库没有的，但已存在的、需添加
			List<SysResource> addList = (List<SysResource>) CollectionUtils.select(hasResList, new Predicate() {
				@Override
				public boolean evaluate(Object object) {
					SysResource tempobj = (SysResource) object;
					return !dbValueList.contains(tempobj.getResValue());
				}
			});

			for (SysResource caResource : addList) {
				int secIndex = caResource.getResValue().indexOf("/", 1);
				int threeIndex = caResource.getResValue().indexOf("/", secIndex + 1);
				caResource.setIcon("icon-user");
				caResource.setIsEdit(YesOrNo.yes.name());
				caResource.setRemark("系统自动同步");
				caResource.setIsSync(YesOrNo.yes.name());
				caResource.setResLevel(2);
				caResource.setBound2(YesOrNo.yes.name());
				sysResourceMapper.insert(caResource);
			}
		} catch (Exception e) {
			ret.setMessage(LK("tip.sys.error.sync") + e.getMessage());
		}
		return TapestryAssist.getTextStreamResponse(ret);
	}

	private String findAttrByName(Document doc, String nodeName) {
		String retstr = null;
		try {
			retstr = doc.getFirstChild().getAttributes().getNamedItem(nodeName).getNodeValue();
		} catch (Exception e) {
		}
		return retstr;
	}

	IOFileFilter fileFilter = new IOFileFilter() {
		@Override
		public boolean accept(File dir, String name) {
			if (name.endsWith(".tml")) {
				return true;
			} else {
				return false;
			}
		}

		@Override
		public boolean accept(File file) {
			String name = file.getName();
			if (name.endsWith(".tml")) {
				return true;
			} else {
				return false;
			}
		}
	};

	IOFileFilter dirFilter = new IOFileFilter() {
		@Override
		public boolean accept(File dir, String name) {
			if (name.endsWith(".tml")) {
				return true;
			} else {
				return false;
			}
		}

		@Override
		public boolean accept(File file) {
			return true;
		}
	};

	@Override
	public void doSave(SysResource t, boolean isInsert) {
		// TODO Auto-generated method stub

	}

	@Override
	public void doDel(String id) {
		// TODO Auto-generated method stub

	}

	@Override
	public BaseMapper<SysResource> getBaseMapper() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void packageQuery(SysResource t, QueryWrapper<SysResource> queryWrapper) {
		// TODO Auto-generated method stub

	}

}
