package nl.rutgerkok.blocklocker.impl.event;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import org.bukkit.block.Sign;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;

import com.google.common.base.Preconditions;

import nl.rutgerkok.blocklocker.BlockLockerPlugin;
import nl.rutgerkok.blocklocker.Permissions;
import nl.rutgerkok.blocklocker.SignType;
import nl.rutgerkok.blocklocker.Translator.Translation;
import nl.rutgerkok.blocklocker.protection.Protection;

public final class BlockLockerCommand implements TabExecutor {

    private final BlockLockerPlugin plugin;

    public BlockLockerCommand(BlockLockerPlugin plugin) {
        this.plugin = Preconditions.checkNotNull(plugin);
    }

    @Override
    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
        if (args.length == 2) {
            return null;
        }
        if (args.length > 2) {
            return Collections.emptyList();
        }
        return Arrays.asList("2", "3", "4");
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (args.length == 0) {
            return false;
        }

        if (args[0].equalsIgnoreCase("reload")) {
            return reloadCommand(sender);
        }
        return signChangeCommand(sender, args);
    }

    private boolean reloadCommand(CommandSender sender) {
        if (!sender.hasPermission(Permissions.CAN_RELOAD)) {
            plugin.getTranslator().sendMessage(sender, Translation.COMMAND_NO_PERMISSION);
            return true;
        }

        plugin.reload();
        plugin.getLogger().info(plugin.getTranslator().getWithoutColor(Translation.COMMAND_PLUGIN_RELOADED));
        if (!(sender instanceof ConsoleCommandSender)) {
            // Avoid sending message twice to the console
            plugin.getTranslator().sendMessage(sender, Translation.COMMAND_PLUGIN_RELOADED);
        }
        return true;
    }

    private boolean signChangeCommand(CommandSender sender, String[] args) {
        if (!(sender instanceof Player)) {
            plugin.getTranslator().sendMessage(sender, Translation.COMMAND_CANNOT_BE_USED_BY_CONSOLE);
            return true;
        }

        Player player = (Player) sender;
        Optional<Sign> selectedSign = plugin.getSignSelector().getSelectedSign(player);
        if (!selectedSign.isPresent()) {
            plugin.getTranslator().sendMessage(player, Translation.COMMAND_NO_SIGN_SELECTED);
            return true;
        }

        if (args.length > 2) {
            return false;
        }

        // Parse line number
        int lineNumber;
        try {
            lineNumber = Integer.parseInt(args[0]);
        } catch (NumberFormatException e) {
            return false;
        }
        if (lineNumber < 2 || lineNumber > 4) {
            plugin.getTranslator().sendMessage(player, Translation.COMMAND_LINE_NUMBER_OUT_OF_BOUNDS);
            return true;
        }

        // Parse name
        String name = args.length > 1 ? args[1] : "";
        if (name.length() > 16) {
            plugin.getTranslator().sendMessage(player, Translation.COMMAND_PLAYER_NAME_TOO_LONG);
            return true;
        }

        // Check protection
        Sign sign = selectedSign.get();
        Optional<SignType> signType = plugin.getSignParser().getSignType(sign);
        Optional<Protection> protection = plugin.getProtectionFinder().findProtection(sign.getBlock());

        if (!protection.isPresent() || !signType.isPresent()) {
            plugin.getTranslator().sendMessage(player, Translation.COMMAND_SIGN_NO_LONGER_PART_OF_PROTECTION);
            return true;
        }

        // Check line number in combination with sign type
        if (signType.get().isMainSign() && lineNumber == 2 && !player.hasPermission(Permissions.CAN_BYPASS)) {
            plugin.getTranslator().sendMessage(player, Translation.COMMAND_CANNOT_EDIT_OWNER);
            return true;
        }

        // Update protection
        sign.setLine(lineNumber - 1, name);
        sign.update();
        plugin.getProtectionUpdater().update(protection.get(), true);
        plugin.getTranslator().sendMessage(player, Translation.COMMAND_UPDATED_SIGN);

        return true;
    }

}

@@ -929,34 +929,25 @@
 lic 
-List%3CString%3E onTabComplete
+boolean onCommand
 (Com
@@ -993,13 +993,13 @@
 ing 
-alias
+label
 , St
@@ -1040,17 +1040,17 @@
 ngth == 
-2
+0
 ) %7B%0A    
@@ -1068,12 +1068,13 @@
 urn 
-null
+false
 ;%0A  
@@ -1073,32 +1073,33 @@
 alse;%0A        %7D%0A
+%0A
         if (args
@@ -1094,35 +1094,54 @@
     if (args
-.length %3E 2
+%5B0%5D.equalsIgnoreCase(%22reload%22)
 ) %7B%0A        
@@ -1155,30 +1155,28 @@
 urn 
-Collections.emptyList(
+reloadCommand(sender
 );%0A 
@@ -1203,35 +1203,38 @@
 urn 
-Arrays.asList(%222%22, %223%22, %224%22
+signChangeCommand(sender, args
 );%0A 
@@ -1264,33 +1264,42 @@
  public 
-boolean onCommand
+List%3CString%3E onTabComplete
 (Command
@@ -1329,37 +1329,37 @@
 command, String 
-label
+alias
 , String%5B%5D args)
@@ -1380,33 +1380,33 @@
 (args.length == 
-0
+2
 ) %7B%0A            
@@ -1404,37 +1404,36 @@
          return 
-false
+null
 ;%0A        %7D%0A%0A   
@@ -1420,33 +1420,32 @@
 null;%0A        %7D%0A
-%0A
         if (args
@@ -1448,38 +1448,19 @@
 args
-%5B0%5D.equalsIgnoreCase(%22reload%22)
+.length %3E 2
 ) %7B%0A
@@ -1478,36 +1478,38 @@
  return 
-reloadCommand(sender
+Collections.emptyList(
 );%0A     
@@ -1532,38 +1532,35 @@
 urn 
-signChangeCommand(sender, args
+Arrays.asList(%222%22, %223%22, %224%22
 );%0A 
@@ -3313,10 +3313,10 @@
 ) %3E 
-16
+25
 ) %7B%0A

Increase max length on signs to 25 using command