/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.catalina.startup;

import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;

import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import org.apache.catalina.Context;
import org.apache.tomcat.unittest.TesterContext;
import org.easymock.EasyMock;
import org.easymock.IMocksControl;

public class TestWebappServiceLoader {
    private static final String CONFIG_FILE =
            "META-INF/services/javax.servlet.ServletContainerInitializer";
    private IMocksControl control;
    private ClassLoader cl;
    private ClassLoader parent;
    private Context context;
    private ServletContext servletContext;
    private WebappServiceLoader<ServletContainerInitializer> loader;

    @Before
    public void init() {
        control = EasyMock.createStrictControl();
        parent = control.createMock(ClassLoader.class);
        cl = EasyMock.createMockBuilder(ClassLoader.class)
                .withConstructor(parent)
                .addMockedMethod("loadClass", String.class)
                .createMock(control);
        servletContext = control.createMock(ServletContext.class);
        EasyMock.expect(servletContext.getClassLoader()).andStubReturn(cl);
        context = new ExtendedTesterContext(servletContext, parent);
    }

    @Test
    public void testNoInitializersFound() throws IOException {
        loader = new WebappServiceLoader<>(context);
        EasyMock.expect(servletContext.getAttribute(ServletContext.ORDERED_LIBS))
                .andReturn(null);
        EasyMock.expect(cl.getResources(CONFIG_FILE))
                .andReturn(Collections.<URL>emptyEnumeration());
        control.replay();
        Assert.assertTrue(loader.load(ServletContainerInitializer.class).isEmpty());
        control.verify();
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testInitializerFromClasspath() throws IOException {
        URL url = new URL("file://test");
        loader = EasyMock.createMockBuilder(WebappServiceLoader.class)
                .addMockedMethod("parseConfigFile", LinkedHashSet.class, URL.class)
                .withConstructor(context).createMock(control);
        EasyMock.expect(servletContext.getAttribute(ServletContext.ORDERED_LIBS))
                .andReturn(null);
        EasyMock.expect(cl.getResources(CONFIG_FILE))
                .andReturn(Collections.enumeration(Collections.singleton(url)));
        loader.parseConfigFile(EasyMock.isA(LinkedHashSet.class), EasyMock.same(url));
        control.replay();
        Assert.assertTrue(loader.load(ServletContainerInitializer.class).isEmpty());
        control.verify();
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testWithOrdering() throws IOException {
        URL url1 = new URL("file://jar1.jar");
        URL sci1 = new URL("jar:file://jar1.jar!/" + CONFIG_FILE);
        URL url2 = new URL("file://dir/");
        URL sci2 = new URL("file://dir/" + CONFIG_FILE);
        loader = EasyMock.createMockBuilder(WebappServiceLoader.class)
                .addMockedMethod("parseConfigFile", LinkedHashSet.class, URL.class)
                .withConstructor(context).createMock(control);
        List<String> jars = Arrays.asList("jar1.jar", "dir/");
        EasyMock.expect(servletContext.getAttribute(ServletContext.ORDERED_LIBS))
                .andReturn(jars);
        EasyMock.expect(servletContext.getResource("/WEB-INF/lib/jar1.jar"))
                .andReturn(url1);
        loader.parseConfigFile(EasyMock.isA(LinkedHashSet.class), EasyMock.eq(sci1));
        EasyMock.expect(servletContext.getResource("/WEB-INF/lib/dir/"))
                .andReturn(url2);
        loader.parseConfigFile(EasyMock.isA(LinkedHashSet.class), EasyMock.eq(sci2));
        EasyMock.expect(parent.getResources(CONFIG_FILE))
                .andReturn(Collections.<URL>emptyEnumeration());

        control.replay();
        Assert.assertTrue(loader.load(ServletContainerInitializer.class).isEmpty());
        control.verify();
    }

    @Test
    public void testParseConfigFile() throws IOException {
        LinkedHashSet<String> found = new LinkedHashSet<>();
        loader = new WebappServiceLoader<>(context);
        loader.parseConfigFile(found, getClass().getResource("service-config.txt"));
        Assert.assertEquals(Collections.singleton("provider1"), found);
    }

    @Test
    public void testLoadServices() throws Exception {
        Class<?> sci = TesterServletContainerInitializer1.class;
        loader = new WebappServiceLoader<>(context);
        cl.loadClass(sci.getName());
        EasyMock.expectLastCall()
                .andReturn(sci);
        LinkedHashSet<String> names = new LinkedHashSet<>();
        names.add(sci.getName());
        control.replay();
        Collection<ServletContainerInitializer> initializers =
                loader.loadServices(ServletContainerInitializer.class, names);
        Assert.assertEquals(1, initializers.size());
        Assert.assertTrue(sci.isInstance(initializers.iterator().next()));
        control.verify();
    }

    @Test
    public void testServiceIsNotExpectedType() throws Exception {
        Class<?> sci = Object.class;
        loader = new WebappServiceLoader<>(context);
        cl.loadClass(sci.getName());
        EasyMock.expectLastCall()
                .andReturn(sci);
        LinkedHashSet<String> names = new LinkedHashSet<>();
        names.add(sci.getName());
        control.replay();
        try {
            loader.loadServices(ServletContainerInitializer.class, names);
        } catch (IOException e) {
            Assert.assertTrue(e.getCause() instanceof ClassCastException);
        } finally {
            control.verify();
        }
    }

    @Test
    public void testServiceCannotBeConstructed() throws Exception {
        Class<?> sci = Integer.class;
        loader = new WebappServiceLoader<>(context);
        cl.loadClass(sci.getName());
        EasyMock.expectLastCall()
                .andReturn(sci);
        LinkedHashSet<String> names = new LinkedHashSet<>();
        names.add(sci.getName());
        control.replay();
        try {
            loader.loadServices(ServletContainerInitializer.class, names);
        } catch (IOException e) {
            Assert.assertTrue(e.getCause() instanceof InstantiationException);
        } finally {
            control.verify();
        }
    }

    private static class ExtendedTesterContext extends TesterContext {
        private final ServletContext servletContext;
        private final ClassLoader parent;

        public ExtendedTesterContext(ServletContext servletContext, ClassLoader parent) {
            this.servletContext = servletContext;
            this.parent = parent;
        }

        @Override
        public ServletContext getServletContext() {
            return servletContext;
        }

        @Override
        public String getContainerSciFilter() {
            return "";
        }

        @Override
        public ClassLoader getParentClassLoader() {
            return parent;
        }

    }
}
