/*
 * 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.commons.chain2.config.xml;

import static org.apache.commons.chain2.testutils.HasCommandCount.hasCommandCount;
import static org.apache.commons.chain2.testutils.HasLog.hasLog;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.net.URL;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.chain2.Catalog;
import org.apache.commons.chain2.CatalogFactory;
import org.apache.commons.chain2.Context;
import org.apache.commons.chain2.Processing;
import org.apache.commons.chain2.testutils.AddingCommand;
import org.apache.commons.chain2.impl.CatalogBase;
import org.apache.commons.chain2.impl.ChainBase;
import org.apache.commons.chain2.impl.ContextBase;
import org.apache.commons.chain2.testutils.DelegatingCommand;
import org.apache.commons.chain2.testutils.DelegatingFilter;
import org.apache.commons.chain2.testutils.ExceptionCommand;
import org.apache.commons.chain2.testutils.ExceptionFilter;
import org.apache.commons.chain2.testutils.NonDelegatingCommand;
import org.apache.commons.chain2.testutils.NonDelegatingFilter;
import org.apache.commons.digester3.Digester;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

/**
 * Parameterized test case for {@link XmlConfigParser}, that uses config locations as data points.
 *
 * <p><strong>Note:</strong> This test case assumes, that all config files will be parsed to the same catalog
 * and command instances.</p>
 *
 * @version $Id$
 */
@RunWith(Parameterized.class)
public class XmlConfigParserTestCase {

    private Catalog<String, Object, Context<String, Object>> catalog = null;
    private Context<String, Object> context = null;
    private XmlConfigParser parser = null;
    private final String configLocation;

    @Parameterized.Parameters
    public static List<Object[]> data() {
        return Arrays.asList(new Object[][]
            {
                {"/org/apache/commons/chain2/config/xml/test-config.xml"},
                {"/org/apache/commons/chain2/config/xml/test-config-2.xml"}
            }
        );
    }

    public XmlConfigParserTestCase(String configLocation) {
        this.configLocation = configLocation;
    }

    @Before
    public void setUp() throws Exception {
        init();
        load(configLocation);
    }

    private void init() {
        CatalogFactory.clear();
        catalog = new CatalogBase<String, Object, Context<String, Object>>();
        context = new ContextBase();
        parser = new XmlConfigParser();
    }

    @After
    public void tearDown() {
        parser = null;
        context = null;
        catalog = null;
    }

    // Load the default test-config.xml file and examine the results
    @Test
    public void testDefault() throws Exception {

        // Check overall command count
        assertThat(catalog, hasCommandCount(17));

        // Check individual single command instances
        {
            AddingCommand command = catalog.getCommand("AddingCommand");
            assertNotNull(command);
        }

        {
            DelegatingCommand command = catalog.getCommand("DelegatingCommand");
            assertNotNull(command);
        }

        {
            DelegatingFilter command = catalog.getCommand("DelegatingFilter");
            assertNotNull(command);
        }

        {
            ExceptionCommand command = catalog.getCommand("ExceptionCommand");
            assertNotNull(command);
        }

        {
            ExceptionFilter command = catalog.getCommand("ExceptionFilter");
            assertNotNull(command);
        }

        {
            NonDelegatingCommand command = catalog.getCommand("NonDelegatingCommand");
            assertNotNull(command);
        }

        {
            NonDelegatingFilter command = catalog.getCommand("NonDelegatingFilter");
            assertNotNull(command);
        }

        ChainBase chain = catalog.getCommand("ChainBase");
        assertNotNull(chain);
        assertTrue(chain instanceof TestChain);

        // Check configurable properties instance
        TestCommand tcommand = catalog.getCommand("Configurable");
        assertNotNull(tcommand);
        assertEquals("Foo Value", tcommand.getFoo());
        assertEquals("Bar Value", tcommand.getBar());

    }


    // Test execution of chain "Execute2a"
    @Test
    public void testExecute2a() throws Exception {

        assertEquals(Processing.FINISHED, catalog.getCommand("Execute2a").execute(context));
        assertThat(context, hasLog("1/2/3"));

    }


    // Test execution of chain "Execute2b"
    @Test
    public void testExecute2b() throws Exception {

        assertEquals(Processing.CONTINUE, catalog.getCommand("Execute2b").execute(context));
        assertThat(context, hasLog("1/2/3"));

    }


    // Test execution of chain "Execute2c"
    @Test
    public void testExecute2c() throws Exception {

        try {
            catalog.getCommand("Execute2c").execute(context);
        } catch (ArithmeticException e) {
            assertEquals("Correct exception id",
                    "3", e.getMessage());
        }
        assertThat(context, hasLog("1/2/3"));

    }


    // Test execution of chain "Execute2d"
    @Test
    public void testExecute2d() throws Exception {

        try {
            catalog.getCommand("Execute2d").execute(context);
        } catch (ArithmeticException e) {
            assertEquals("Correct exception id",
                    "2", e.getMessage());
        }
        assertThat(context, hasLog("1/2"));

    }


    // Test execution of chain "Execute4a"
    @Test
    public void testExecute4a() throws Exception {

        assertEquals(Processing.FINISHED, catalog.getCommand("Execute4a").execute(context));
        assertThat(context, hasLog("1/2/3/c/a"));

    }


    // Test execution of chain "Execute2b"
    @Test
    public void testExecute4b() throws Exception {

        assertEquals(Processing.CONTINUE, catalog.getCommand("Execute4b").execute(context));
        assertThat(context, hasLog("1/2/3/b"));

    }


    // Test execution of chain "Execute4c"
    @Test
    public void testExecute4c() throws Exception {

        try {
            catalog.getCommand("Execute4c").execute(context);
        } catch (ArithmeticException e) {
            assertEquals("Correct exception id",
                    "3", e.getMessage());
        }
        assertThat(context, hasLog("1/2/3/c/b/a"));

    }


    // Test execution of chain "Execute4d"
    @Test
    public void testExecute4d() throws Exception {

        try {
            catalog.getCommand("Execute4d").execute(context);
        } catch (ArithmeticException e) {
            assertEquals("Correct exception id",
                    "2", e.getMessage());
        }
        assertThat(context, hasLog("1/2/b/a"));

    }


    // Test a pristine ConfigParser instance
    @Test
    public void testPristine() throws Exception {

        init();
        // Validate the "digester" property
        Digester digester = parser.getDigester();
        assertNotNull("Returned a Digester instance", digester);
        assertFalse("Default namespaceAware",
                digester.getNamespaceAware());
        assertTrue("Default useContextClassLoader",
                digester.getUseContextClassLoader());
        assertFalse("Default validating",
                digester.getValidating());

        // Validate the "ruleSet" property
        ConfigRuleSet ruleSet = (ConfigRuleSet) parser.getRuleSet();
        assertNotNull("Returned a RuleSet instance", ruleSet);
        assertEquals("Default chainElement",
                "chain", ruleSet.getChainElement());
        assertEquals("Default classAttribute",
                "className", ruleSet.getClassAttribute());
        assertEquals("Default commandElement",
                "command", ruleSet.getCommandElement());
        assertEquals("Default nameAttribute",
                "name", ruleSet.getNameAttribute());
        assertNull("Default namespaceURI",
                ruleSet.getNamespaceURI());

        // Validate the "useContextClassLoader" property
        assertTrue("Defaults to use context class loader",
                parser.getUseContextClassLoader());

        // Ensure that there are no preconfigured commands in the catalog
        assertThat(catalog, hasCommandCount(0));

    }

    // Load the specified catalog from the specified resource path
    private void load(String path) throws Exception {
        URL url = getClass().getResource(path);

        if (url == null) {
            String msg = String.format("Can't find resource for path: %s", path);
            throw new IllegalArgumentException(msg);
        }

        CatalogFactory<String, Object, Context<String, Object>> catalogFactory = parser.parse(url);
        catalog = catalogFactory.getCatalog("foo");
    }

}
