/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.bekvon.bukkit.residence.permissions;

import com.bekvon.bukkit.residence.Residence;
import com.bekvon.bukkit.residence.protection.FlagPermissions;
import com.bekvon.bukkit.residence.vaultinterface.ResidenceVaultAdapter;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Server;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;

/**
 * 
 * @author Administrator
 */
public class PermissionManager {
	protected static PermissionsInterface perms;
	protected Map<String, PermissionGroup> groups;
	protected Map<String, String> playersGroup;
	protected FlagPermissions globalFlagPerms;

	public PermissionManager(FileConfiguration config) {
		try {
			groups = Collections
					.synchronizedMap(new HashMap<String, PermissionGroup>());
			playersGroup = Collections
					.synchronizedMap(new HashMap<String, String>());
			globalFlagPerms = new FlagPermissions();
			this.readConfig(config);
			boolean enable = config
					.getBoolean("Global.EnablePermissions", true);
			if (enable) {
				this.checkPermissions();
			}
		} catch (Exception ex) {
			Logger.getLogger(PermissionManager.class.getName()).log(
					Level.SEVERE, null, ex);
		}
	}

	public PermissionGroup getGroup(Player player) {
		return groups.get(this.getGroupNameByPlayer(player));
	}

	public PermissionGroup getGroup(String player, String world) {
		return groups.get(this.getGroupNameByPlayer(player, world));
	}

	public PermissionGroup getGroupByName(String group) {
		group = group.toLowerCase();
		if (!groups.containsKey(group)) {
			return groups.get(Residence.getConfigManager().getDefaultGroup());
		}
		return groups.get(group);
	}

	public String getGroupNameByPlayer(Player player) {
		return this.getGroupNameByPlayer(player.getName(), player.getWorld()
				.getName());
	}

	public String getGroupNameByPlayer(String player, String world) {
		player = player.toLowerCase();
		if (playersGroup.containsKey(player)) {
			String group = playersGroup.get(player);
			if (group != null) {
				group = group.toLowerCase();
				if (group != null && groups.containsKey(group)) {
					return group;
				}
			}
		}
		String group = this.getPermissionsGroup(player, world);
		if (group == null || !groups.containsKey(group)) {
			return Residence.getConfigManager().getDefaultGroup().toLowerCase();
		} else {
			return group;
		}
	}

	public String getPermissionsGroup(Player player) {
		return this.getPermissionsGroup(player.getName(), player.getWorld()
				.getName());
	}

	public String getPermissionsGroup(String player, String world) {
		if (perms == null)
			return Residence.getConfigManager().getDefaultGroup();
		return perms.getPlayerGroup(player, world);
	}

	public boolean isResidenceAdmin(Player player) {
		return (player.hasPermission("residence.admin") || (player.isOp() && Residence
				.getConfigManager().getOpsAreAdmins()));
	}

	private void checkPermissions() {
		Server server = Residence.getServ();
		Plugin p = server.getPluginManager().getPlugin("Vault");
		if (p != null) {
			ResidenceVaultAdapter vault = new ResidenceVaultAdapter(server);
			if (vault.permissionsOK()) {
				perms = vault;
				Logger.getLogger("Minecraft").log(
						Level.INFO,
						"[Residence] 发现 Vault 使用权限系统:"
								+ vault.getPermissionsName());
				return;
			} else {
				Logger.getLogger("Minecraft")
						.log(Level.INFO,
								"[Residence] 发现 Vault, 但是 Vault 未找到权限系统...");
			}
		}
		Logger.getLogger("Minecraft").log(Level.INFO,
				"[Residence] 权限系统未找到!");
	}

	private void readConfig(FileConfiguration config) {
		String defaultGroup = Residence.getConfigManager().getDefaultGroup();
		globalFlagPerms = FlagPermissions.parseFromConfigNode("FlagPermission",
				config.getConfigurationSection("Global"));
		ConfigurationSection nodes = config.getConfigurationSection("Groups");
		if (nodes != null) {
			Set<String> entrys = nodes.getKeys(false);
			for (String key : entrys) {
				try {
					groups.put(
							key.toLowerCase(),
							new PermissionGroup(key.toLowerCase(), nodes
									.getConfigurationSection(key),
									globalFlagPerms));
					List<String> mirrors = nodes.getConfigurationSection(key)
							.getStringList("Mirror");
					for (String group : mirrors) {
						groups.put(
								group.toLowerCase(),
								new PermissionGroup(key.toLowerCase(), nodes
										.getConfigurationSection(key),
										globalFlagPerms));
					}
				} catch (Exception ex) {
					System.out
							.println("[Residence] 错误 从配置文件读取:"
									+ key + " 抛出异常:" + ex);
				}
			}
		}
		if (!groups.containsKey(defaultGroup)) {
			groups.put(defaultGroup, new PermissionGroup(defaultGroup));
		}
		Set<String> keys = config.getConfigurationSection("GroupAssignments")
				.getKeys(false);
		if (keys != null) {
			for (String key : keys) {
				playersGroup.put(
						key.toLowerCase(),
						config.getString("GroupAssignments." + key,
								defaultGroup).toLowerCase());
			}
		}
	}

	public boolean hasGroup(String group) {
		group = group.toLowerCase();
		return groups.containsKey(group);
	}

	public PermissionsInterface getPermissionsPlugin() {
		return perms;
	}
}
