package com.wb.interact;

import java.io.File;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wb.common.KVBuffer;
import org.json.JSONArray;
import org.json.JSONObject;

import com.wb.common.XwlBuffer;
import com.wb.util.SortUtil;
import com.wb.util.SysUtil;
import com.wb.util.WebUtil;

public class Tools {
	/**
	 * 获取数据字典数据库表树数据。
	 */
	public static void getDictTree(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String type = request.getParameter("type");
		String jndi = request.getParameter("jndi");
		String schema = request.getParameter("schema");
		String result;
		HashSet<String> tables, copyTables;

		if ("db".equals(type)) {
			tables = getDictTables(request, jndi);
			copyTables = new HashSet<String>();//getSchemaList会删除tables中的值，因此建立一个副本
			for (String t : tables) {
				copyTables.add(t);
			}
			result = com.wb.interact.DBE.getSchemaList(jndi, tables);
			//如果没有Schema直接返回表列表
			if (result == null)
				result = com.wb.interact.DBE.getTableList(jndi, null, copyTables);
		} else if ("schema".equals(type)) {
			result = com.wb.interact.DBE.getTableList(jndi, schema, getDictTables(request, jndi));
		} else
			result = com.wb.interact.DBE.getDbList();
		WebUtil.send(response, result);
	}

	/**
	 * 获取所有已经定义的字典表表名集。
	 * @param request 请求对象。
	 * @param jndi 数据库JNDI。
	 */
	private static HashSet<String> getDictTables(HttpServletRequest request, String jndi) throws Exception {
		String tableName;
		boolean otherDb = !"default".equals(jndi);
		int jndiLen = jndi.length() + 1;
		HashSet<String> tables = new HashSet<String>();
		ResultSet rs = (ResultSet) com.wb.util.DbUtil.run(request, "select distinct TABLE_NAME from WB_DICT");

		jndi = jndi.toUpperCase() + '.';
		while (rs.next()) {
			// DICT表名不区分大小写以统一不同数据库差异
			tableName = rs.getString(1).toUpperCase();
			if (otherDb) {
				if (tableName.startsWith(jndi))
					tables.add(tableName.substring(jndiLen));
			} else if (tableName.indexOf('.') == -1) //表名不区分Schema，只按表名识别
				tables.add(tableName);
		}
		return tables;
	}

	/**
	 * 获取所有键名组成的数组，并设置到request attribute名为keyNameList为属性中。
	 */
	public static void loadKeyNames(HttpServletRequest request, HttpServletResponse response) {
		boolean isFirst = true;
		StringBuilder buf = new StringBuilder();
		ArrayList<Entry<String, ConcurrentHashMap<Object, String>>> keys = SortUtil
				.sortKey(KVBuffer.buffer);

		buf.append("[");
		for (Entry<String, ConcurrentHashMap<Object, String>> key : keys) {
			if (isFirst)
				isFirst = false;
			else
				buf.append(",");
			buf.append(com.wb.util.StringUtil.quote(key.getKey()));
		}
		buf.append("]");
		request.setAttribute("keyNameList", com.wb.util.StringUtil.quote(buf.toString(), false));
	}

	/**
	 * 获取所有模块的角色信息。
	 */
	public static void getModulesPerm(HttpServletRequest request, HttpServletResponse response) throws Exception {
		JSONObject perms = new JSONObject();
		scanModulePerm(com.wb.common.Base.modulePath, perms);
		WebUtil.send(response, perms);
	}

	/**
	 * 对指定目录下的模块进行扫描，并获取这些模块的权限信息至JSONObject。
	 * @param path 路径。
	 * @param perms 获取的模块角色列表。
	 */
	private static void scanModulePerm(File path, JSONObject perms) throws Exception {
		File files[] = com.wb.util.FileUtil.listFiles(path);
		JSONObject jo;
		JSONObject roles;
		String filename;

		for (File file : files) {
			if (file.isDirectory()) {
				scanModulePerm(file, perms);
			} else {
				filename = file.getName();
				if (!filename.endsWith(".xwl"))
					continue;
				jo = com.wb.util.JsonUtil.readObject(file);
				System.out.println(file.getAbsolutePath()+"==="+filename);
				roles = (JSONObject) jo.opt("roles");
				perms.put(com.wb.util.FileUtil.getModulePath(file), roles);
			}
		}
	}

	/**
	 * 删除所有模块中的指定角色信息。
	 */
	public static void delModulesPerm(HttpServletRequest request, HttpServletResponse response) throws Exception {
		JSONArray destroy = new JSONArray(request.getParameter("destroy"));
		int i, j = destroy.length();
		if (j == 0)
			return;
		String[] roles = new String[j];

		for (i = 0; i < j; i++)
			roles[i] = destroy.getJSONObject(i).getString("ROLE_ID");
		doDelPerm(com.wb.common.Base.modulePath, roles);
	}

	/**
	 * 对指定目录下的模块进行扫描，并删除模块文件内指定的角色信息。
	 * @param path 路径。
	 * @param roles 删除的模块角色列表。
	 */
	private static void doDelPerm(File path, String[] delRoles) throws Exception {
		File files[] = com.wb.util.FileUtil.listFiles(path);
		String filename;

		for (File file : files) {
			if (file.isDirectory()) {
				doDelPerm(file, delRoles);
			} else {
				filename = file.getName();
				if (filename.endsWith(".xwl"))
					com.wb.interact.IDE.updateModule(file, null, delRoles, false);
			}
		}
	}

	/**
	* 设置指定模块列表的角色信息。
	*/
	public static void setModulesPerm(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String[] roles = new String[1], userRoles = com.wb.common.Session.getRoles(request);
		boolean checked = Boolean.parseBoolean(request.getParameter("checked"));
		JSONArray pathList = new JSONArray(request.getParameter("path"));
		int i, j = pathList.length();
		File file;

		roles[0] = request.getParameter("role");
		for (i = 0; i < j; i++) {
			file = new File(com.wb.common.Base.modulePath, pathList.getString(i));
			// 禁止无权限的用户设置该权限
			if (!file.isDirectory()) {
				if (!XwlBuffer.canAccess(XwlBuffer.get(com.wb.util.FileUtil.getModulePath(file), false), userRoles))
					SysUtil.accessDenied();
				com.wb.interact.IDE.updateModule(file, null, roles, checked);
			}
		}
	}
}
