/*
 * Copyright © 2015, Leon Mangler and the SuperVanish contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package de.myzelyam.supervanish;

import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;

import de.myzelyam.supervanish.hooks.PlaceholderAPIHook;
import de.myzelyam.supervanish.utils.Validation;

import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.permission.Permission;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;

import java.util.Arrays;
import java.util.List;

import be.maximvdw.placeholderapi.PlaceholderAPI;

public class PlaceholderConverter {

    private final SuperVanish plugin;

    public PlaceholderConverter(SuperVanish plugin) {
        this.plugin = plugin;
    }

    public String replacePlaceholders(String msg, Object... additionalPlayerInfo) {
        Validation.checkIsTrue("Failed to replace variables (Illegal arguments)",
                msg != null, additionalPlayerInfo != null);
        //noinspection ConstantConditions
        Validation.checkIsTrue(additionalPlayerInfo.length > 0);
        // // check vararg
        final List<Object> additionalPlayerInfoList = Arrays
                .asList(additionalPlayerInfo);
        Object unspecifiedPlayer = additionalPlayerInfoList.get(0);
        String unspecifiedOtherPlayersName = null;
        if (additionalPlayerInfoList.size() > 1
                && (additionalPlayerInfoList.get(1) instanceof String
                || additionalPlayerInfoList.get(1) instanceof Player)) {
            unspecifiedOtherPlayersName = (String) (additionalPlayerInfoList
                    .get(1) instanceof Player
                    ? ((Player) additionalPlayerInfoList.get(1)).getName()
                    : additionalPlayerInfoList.get(1));
        }
        //noinspection ConstantConditions
        msg = msg.replace("\\n", "\n");
        // replace sender specific variables
        replaceVariables:
        {
            if (unspecifiedPlayer instanceof OfflinePlayer
                    && !(unspecifiedPlayer instanceof Player)) {
                // offline player
                OfflinePlayer specifiedPlayer = (OfflinePlayer) unspecifiedPlayer;
                // MVdWPlaceholderAPI
                if (Bukkit.getPluginManager().isPluginEnabled("MVdWPlaceholderAPI")
                        && plugin.getSettings().getBoolean("HookOptions.EnableMVdWPlaceholderAPIHook", true)) {
                    String replaced = PlaceholderAPI.replacePlaceholders(specifiedPlayer, msg);
                    msg = replaced == null ? msg : replaced;
                }
                // replace essentials nick names
                if (Bukkit.getPluginManager()
                        .getPlugin("Essentials") != null) {
                    msg = msg.replace("%nick%", specifiedPlayer.getName());
                }
                // replace general variables
                msg = msg.replace("%d%", specifiedPlayer.getName())
                        .replace("%p%", specifiedPlayer.getName())
                        .replace("%tab%", specifiedPlayer.getName());
                // replace other player's name if possible
                msg = msg.replace("%other%", unspecifiedOtherPlayersName != null
                        ? unspecifiedOtherPlayersName : "UNKNOWN");
                break replaceVariables;
            }
            if (unspecifiedPlayer instanceof Player) {
                // player
                Player specifiedPlayer = (Player) unspecifiedPlayer;
                // PlaceholderAPI
                if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")
                        && plugin.getSettings().getBoolean("HookOptions.EnablePlaceholderAPIHook", true)) {
                    String replaced = PlaceholderAPIHook.translatePlaceholders(msg, specifiedPlayer);
                    //noinspection ConstantConditions
                    msg = replaced == null ? msg : replaced;
                }
                // MVdWPlaceholderAPI
                if (Bukkit.getPluginManager().isPluginEnabled("MVdWPlaceholderAPI")
                        && plugin.getSettings().getBoolean("HookOptions.EnableMVdWPlaceholderAPIHook", true)) {
                    String replaced = PlaceholderAPI.replacePlaceholders(specifiedPlayer, msg);
                    msg = replaced == null ? msg : replaced;
                }
                // replace essentials nick names
                if (Bukkit.getPluginManager().getPlugin("Essentials") != null) {
                    Essentials ess = (Essentials) Bukkit.getServer()
                            .getPluginManager().getPlugin("Essentials");
                    User u = ess.getUser(specifiedPlayer);
                    if (u != null)
                        if (u.getNickname() != null)
                            msg = msg.replace("%nick%", u.getNickname());
                }
                // replace vault info
                if (Bukkit.getPluginManager().getPlugin("Vault") != null) {
                    RegisteredServiceProvider<Permission> permService = plugin.getServer()
                            .getServicesManager().getRegistration(Permission.class);
                    RegisteredServiceProvider<Chat> chatService = plugin.getServer()
                            .getServicesManager().getRegistration(Chat.class);
                    Permission permAPI = permService != null ? permService.getProvider() : null;
                    Chat chatAPI = chatService != null ? chatService.getProvider() : null;
                    if (permAPI != null) {
                        String group = permAPI.getPrimaryGroup(specifiedPlayer);
                        if (group != null)
                            msg = msg.replace("%group%", group);
                    }
                    if (chatAPI != null) {
                        String prefix = chatAPI.getPlayerPrefix(specifiedPlayer);
                        String suffix = chatAPI.getPlayerSuffix(specifiedPlayer);
                        if (prefix != null) {
                            msg = msg.replace("%prefix%", prefix);
                        }
                        if (suffix != null) {
                            msg = msg.replace("%suffix%", suffix);
                        }
                    }
                }
                // replace general variables
                msg = msg.replace("%d%", "" + specifiedPlayer.getDisplayName())
                        .replace("%p%", "" + specifiedPlayer.getName())
                        .replace("%tab%",
                                "" + specifiedPlayer.getPlayerListName());
                // replace other player's name if possible
                msg = msg.replace("%other%", unspecifiedOtherPlayersName != null
                        ? unspecifiedOtherPlayersName : "UNKNOWN");

                break replaceVariables;
            }
            if (unspecifiedPlayer instanceof CommandSender) {
                // console
                // replace general variables
                msg = msg.replace("%d%", "Console").replace("%p%", "Console")
                        .replace("%tab%", "Console");
                // replace other player's name if possible
                msg = msg.replace("%other%", unspecifiedOtherPlayersName != null
                        ? unspecifiedOtherPlayersName : "UNKNOWN");
            }
        }
        // convert color codes
        msg = ChatColor.translateAlternateColorCodes('&', msg);
        // return converted message
        return msg;
    }
}

@@ -5841,32 +5841,62 @@
 vider() : null;%0A
+                    try %7B%0A    
                 
@@ -5914,32 +5914,36 @@
 mAPI != null) %7B%0A
+    
                 
@@ -6027,24 +6027,28 @@
             
+    
 if (group !=
@@ -6046,32 +6046,36 @@
 (group != null)%0A
+    
                 
@@ -6135,34 +6135,42 @@
                 
+   
+ 
 %7D%0A
+    
                 
@@ -6188,32 +6188,36 @@
 tAPI != null) %7B%0A
+    
                 
@@ -6302,24 +6302,28 @@
             
+  
+  
 String suffi
@@ -6360,32 +6360,36 @@
 ecifiedPlayer);%0A
+    
                 
@@ -6438,32 +6438,36 @@
                 
+    
 msg = msg.replac
@@ -6505,34 +6505,42 @@
                 
+ 
-%7D%0A
+   %7D%0A    
                 
@@ -6561,32 +6561,36 @@
 ffix != null) %7B%0A
+    
                 
@@ -6656,33 +6656,133 @@
                 
-%7D
+    %7D%0A                        %7D%0A                    %7D catch (UnsupportedOperationException ignored) %7B
 %0A               

Fix UnsupportedOperationException in Vault placeholder replacer