/*
 * BaseRouteTest.java
 *
 * Copyright (c) 2014 Graham Howden <graham_howden1 at yahoo.co.uk>.
 *
 * This file is part of PluginFramework.
 *
 * PluginFramework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PluginFramework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PluginFramework.  If not, see <http ://www.gnu.org/licenses/>.
 */

package com.publicuhc.pluginframework.commands.routing;

import com.publicuhc.pluginframework.commands.requests.SenderType;
import com.publicuhc.pluginframework.commands.routes.*;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.junit.Before;
import org.junit.Test;

import java.util.regex.Pattern;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;

public class RouteTest {

    private Route baseRoute;

    @Before
    public void onStartUp() {
        baseRoute = new BaseRoute();
    }

    @Test
    public void testBaseRoute() {
        assertTrue(baseRoute.matches(mock(CommandSender.class), mock(Command.class), ""));
    }

    @Test
    public void testCommandRestrictedRoute() {
        Command valid = mock(Command.class);
        when(valid.getName()).thenReturn("valid");

        Command invalid = mock(Command.class);
        when(invalid.getName()).thenReturn("invalid");

        CommandRestrictedRoute route = new CommandRestrictedRoute(baseRoute, "valid");

        assertTrue(route.matches(mock(CommandSender.class), valid, ""));
        assertFalse(route.matches(mock(CommandSender.class), invalid, ""));
    }

    @Test
    public void testPatternRestrictedRoute() {
        PatternRestrictedRoute route = new PatternRestrictedRoute(baseRoute, Pattern.compile("(valid|good)"));

        assertTrue(route.matches(mock(CommandSender.class), mock(Command.class), "valid"));
        assertTrue(route.matches(mock(CommandSender.class), mock(Command.class), "good"));
        assertFalse(route.matches(mock(CommandSender.class), mock(Command.class), "invalid"));
    }

    @Test
    public void testPermissionRestrictedRoute() {
        CommandSender goodsender = mock(CommandSender.class);
        when(goodsender.hasPermission(anyString())).thenReturn(true);

        CommandSender badsender = mock(CommandSender.class);
        when(badsender.hasPermission(anyString())).thenReturn(false);

        PermissionRestrictedRoute route = new PermissionRestrictedRoute(baseRoute, "test.permission");

        assertTrue(route.matches(goodsender, mock(Command.class), ""));
        assertFalse(route.matches(badsender, mock(Command.class), ""));
    }

    @Test
    public void testSenderTypeRestrictedRoute() {
        Player player = mock(Player.class);
        BlockCommandSender block = mock(BlockCommandSender.class);

        SenderTypeRestrictedRoute route = new SenderTypeRestrictedRoute(baseRoute, SenderType.PLAYER);

        assertTrue(route.matches(player, mock(Command.class), ""));
        assertFalse(route.matches(block, mock(Command.class), ""));
    }

    @Test
    public void testMultipleLayers() {
        Player goodPlayer = mock(Player.class);
        when(goodPlayer.hasPermission(anyString())).thenReturn(true);

        Player badPlayer = mock(Player.class);
        when(badPlayer.hasPermission(anyString())).thenReturn(false);

        BlockCommandSender block = mock(BlockCommandSender.class);
        when(block.hasPermission(anyString())).thenReturn(true);

        Command valid = mock(Command.class);
        when(valid.getName()).thenReturn("valid");

        Command invalid = mock(Command.class);
        when(invalid.getName()).thenReturn("invalid");

        SenderTypeRestrictedRoute senderRestricted = new SenderTypeRestrictedRoute(baseRoute, SenderType.PLAYER);
        CommandRestrictedRoute commandRestricted = new CommandRestrictedRoute(senderRestricted, "valid");
        PermissionRestrictedRoute permissionRestricted = new PermissionRestrictedRoute(commandRestricted, "test.permission");

        //test valid first
        assertTrue(permissionRestricted.matches(goodPlayer, valid, ""));

        //test bad permission
        assertFalse(permissionRestricted.matches(badPlayer, valid, ""));

        //test bad type
        assertFalse(permissionRestricted.matches(block, valid, ""));

        //test bad command
        assertFalse(permissionRestricted.matches(goodPlayer, invalid, ""));
    }
}

@@ -1678,31 +1678,32 @@
 e(baseRoute.
-m
+allM
 atch
-es
 (mock(Comman
@@ -2114,39 +2114,40 @@
 ssertTrue(route.
-m
+allM
 atch
-es
 (mock(CommandSen
@@ -2189,39 +2189,40 @@
 sertFalse(route.
-m
+allM
 atch
-es
 (mock(CommandSen
@@ -2441,39 +2441,40 @@
 ssertTrue(route.
-m
+allM
 atch
-es
 (mock(CommandSen
@@ -2534,39 +2534,40 @@
 ssertTrue(route.
-m
+allM
 atch
-es
 (mock(CommandSen
@@ -2635,23 +2635,24 @@
 e(route.
-m
+allM
 atch
-es
 (mock(Co
@@ -3166,23 +3166,24 @@
 e(route.
-m
+allM
 atch
-es
 (goodsen
@@ -3240,23 +3240,24 @@
 e(route.
-m
+allM
 atch
-es
 (badsend
@@ -3595,23 +3595,24 @@
 e(route.
-m
+allM
 atch
-es
 (player,
@@ -3665,23 +3665,24 @@
 e(route.
-m
+allM
 atch
-es
 (block, 
@@ -4740,39 +4740,40 @@
 ssionRestricted.
-m
+allM
 atch
-es
 (goodPlayer, val
@@ -4854,23 +4854,24 @@
 tricted.
-m
+allM
 atch
-es
 (badPlay
@@ -4953,23 +4953,24 @@
 tricted.
-m
+allM
 atch
-es
 (block, 
@@ -5055,15 +5055,16 @@
 ted.
-m
+allM
 atch
-es
 (goo

use new methods in the tests