/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gravitee.plugin.core;

import io.gravitee.common.event.EventManager;
import io.gravitee.plugin.api.ClassLoaderFactory;
import io.gravitee.plugin.api.Plugin;
import io.gravitee.plugin.internal.ClassLoaderFactoryImpl;
import io.gravitee.plugin.internal.PluginRegistryImpl;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

import java.net.URL;

import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

/**
 * @author David BRASSELY (brasseld at gmail.com)
 */
public class PluginRegistryTest {

    private ClassLoaderFactory classLoaderFactory;

    @Before
    public void setUp() {
        classLoaderFactory = new ClassLoaderFactoryImpl();
    }

    @Test(expected = RuntimeException.class)
    public void startWithInvalidWorkspace() throws Exception {
        PluginRegistryImpl pluginRegistry = new PluginRegistryImpl();
        pluginRegistry.start();
    }

    @Test(expected = RuntimeException.class)
    public void startWithInexistantWorkspace() throws Exception {
        PluginRegistryImpl pluginRegistry = new PluginRegistryImpl(
                "/io/gravitee/plugin/invalid/");
        pluginRegistry.start();
    }

    @Test
    public void startWithEmptyWorkspace() throws Exception {
        URL dir = PluginRegistryTest.class.getResource("/io/gravitee/plugin/empty-workspace/");
        PluginRegistryImpl pluginRegistry = new PluginRegistryImpl(dir.getPath());
        pluginRegistry.start();

        Assert.assertTrue(pluginRegistry.plugins().isEmpty());
    }

    @Test
    public void startTwiceWorkspace() throws Exception {
        URL dir = PluginRegistryTest.class.getResource("/io/gravitee/plugin/workspace/");
        PluginRegistryImpl pluginRegistry = Mockito.spy(new PluginRegistryImpl(dir.getPath()));
        pluginRegistry.setClassLoaderFactory(classLoaderFactory);
        pluginRegistry.setEventManager(mock(EventManager.class));
        pluginRegistry.start();
        verify(pluginRegistry, atMost(1)).init();

        pluginRegistry.start();
        verify(pluginRegistry, atMost(1)).init();
    }

    @Test
    public void startWithWorkspace_noJar() throws Exception {
        URL dir = PluginRegistryTest.class.getResource("/io/gravitee/plugin/invalid-workspace-nojar/");
        PluginRegistryImpl pluginRegistry = new PluginRegistryImpl(dir.getPath());
        pluginRegistry.start();

        Assert.assertTrue(pluginRegistry.plugins().isEmpty());
    }

    @Test
    public void startWithValidWorkspace_onePolicyDefstartion() throws Exception {
        URL dir = PluginRegistryTest.class.getResource("/io/gravitee/plugin/workspace/");
        PluginRegistryImpl pluginRegistry = new PluginRegistryImpl(dir.getPath());
        pluginRegistry.setClassLoaderFactory(classLoaderFactory);
        pluginRegistry.setEventManager(mock(EventManager.class));
        pluginRegistry.start();

        Assert.assertEquals(1, pluginRegistry.plugins().size());
    }

    @Test
    public void startWithValidWorkspace_checkPluginDescriptor() throws Exception {
        URL dir = PluginRegistryTest.class.getResource("/io/gravitee/plugin/workspace/");
        PluginRegistryImpl pluginRegistry = new PluginRegistryImpl(dir.getPath());
        pluginRegistry.setClassLoaderFactory(classLoaderFactory);
        pluginRegistry.setEventManager(mock(EventManager.class));
        pluginRegistry.start();

        Assert.assertEquals(1, pluginRegistry.plugins().size());

        Plugin plugin = pluginRegistry.plugins().iterator().next();
        Assert.assertEquals("my-policy", plugin.id());
        Assert.assertEquals("my.project.gravitee.policies.MyPolicy", plugin.clazz().getName());
    }
}

@@ -1033,90 +1033,36 @@
 RL;%0A
-%0A
 import 
-static org.mockito.Mockito.atMost;%0Aimport static org.mockito.Mockito.mock;
+java.net.URLDecoder;%0A
 %0Aimp
@@ -1092,22 +1092,17 @@
 Mockito.
-verify
+*
 ;%0A%0A/**%0A 
@@ -2055,32 +2055,50 @@
 ginRegistryImpl(
+URLDecoder.decode(
 dir.getPath());%0A
@@ -2086,32 +2086,42 @@
 de(dir.getPath()
+, %22UTF-8%22)
 );%0A        plugi
@@ -2438,32 +2438,50 @@
 ginRegistryImpl(
+URLDecoder.decode(
 dir.getPath()));
@@ -2477,16 +2477,26 @@
 etPath()
+, %22UTF-8%22)
 ));%0A    
@@ -3030,32 +3030,50 @@
 ginRegistryImpl(
+URLDecoder.decode(
 dir.getPath());%0A
@@ -3061,32 +3061,42 @@
 de(dir.getPath()
+, %22UTF-8%22)
 );%0A        plugi
@@ -3426,32 +3426,50 @@
 ginRegistryImpl(
+URLDecoder.decode(
 dir.getPath());%0A
@@ -3457,32 +3457,42 @@
 de(dir.getPath()
+, %22UTF-8%22)
 );%0A        plugi
@@ -3965,16 +3965,34 @@
 tryImpl(
+URLDecoder.decode(
 dir.getP
@@ -3996,16 +3996,26 @@
 etPath()
+, %22UTF-8%22)
 );%0A     

allow special characters in path