/*
 * 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.sling.commons.log.logback.integration;

import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;

import javax.inject.Inject;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.slf4j.LoggerFactory;

import static org.apache.sling.commons.log.logback.integration.ITConfigFragments.RESET_EVENT_TOPIC;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.ops4j.pax.exam.CoreOptions.composite;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;

@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class ITAppenderServices extends LogTestBase {

    @Inject
    private BundleContext bundleContext;

    @Inject
    private ConfigurationAdmin ca;

    private ServiceRegistration sr;

    @Inject
    private EventAdmin eventAdmin;

    static {
        // uncomment to enable debugging of this test class
        // paxRunnerVmOption = DEBUG_VM_OPTION;

    }

    @Override
    protected Option addExtraOptions() {
        return composite(
                configAdmin(), mavenBundle("commons-io", "commons-io").versionAsInProject(),
                mavenBundle("org.apache.felix", "org.apache.felix.eventadmin").versionAsInProject()
        );
    }

    @Test
    public void testAppenderService() throws Exception {
        TestAppender ta = registerAppender("foo.bar", "foo.baz");
        delay();

        Logger bar = (Logger)LoggerFactory.getLogger("foo.bar");
        bar.setLevel(Level.DEBUG);
        Logger baz = (Logger)LoggerFactory.getLogger("foo.baz");
        baz.setLevel(Level.INFO);

        bar.debug("Test message");
        baz.debug("Test message"); // Would not be logged

        // One event should be logged.
        assertEquals(1, ta.events.size());
    }

    @Test
    public void testRootAppenderService() throws Exception {
        TestAppender ta = registerAppender("ROOT");
        delay();

        Logger root = (Logger)LoggerFactory.getLogger("ROOT");
        root.setLevel(Level.DEBUG);
        Logger foobar = (Logger)LoggerFactory.getLogger("foo.bar");
        foobar.setLevel(Level.INFO);

        root.debug("one");
        foobar.debug("two");
        foobar.info("three");

        assertEquals(2, ta.events.size());
    }

    @Test
    public void testAppenderServiceModified() throws Exception {
        TestAppender ta = registerAppender("foo.bar", "foo.baz");
        delay();

        Logger bar = (Logger)LoggerFactory.getLogger("foo.bar");
        bar.setLevel(Level.DEBUG);
        Logger baz = (Logger)LoggerFactory.getLogger("foo.baz");
        baz.setLevel(Level.INFO);

        bar.debug("Test message");
        baz.debug("Test message"); // Would not be logged

        // One event should be logged.
        assertEquals(1, ta.events.size());

        ta.reset();

        Dictionary<String, Object> props = new Hashtable<String, Object>();
        props.put("loggers", new String[]{"foo.bar2"});
        sr.setProperties(props);

        delay();
        LoggerFactory.getLogger("foo.bar2").info("foo.bar2");
        LoggerFactory.getLogger("foo.baz").info("foo.baz");

        assertEquals(1, ta.msgs.size());
        assertTrue(ta.msgs.contains("foo.bar2"));
        assertFalse(ta.msgs.contains("foo.baz"));
    }

    @Test
    public void testOsgiAppenderRef() throws Exception {
        Configuration config = ca.getConfiguration(ITConfigAdminSupport.PID, null);
        Dictionary<String, Object> p = new Hashtable<String, Object>();
        p.put(ITConfigAdminSupport.LOG_LEVEL, "INFO");
        p.put(ITConfigAdminSupport.LOGBACK_FILE,absolutePath("test-osg-appender-ref-config.xml"));
        config.update(p);

        delay();

        Logger ref = (Logger)LoggerFactory.getLogger("foo.ref.osgi");
        assertTrue(ref.isDebugEnabled());

        TestAppender ta = registerAppender("foo.bar", "foo.baz");
        delay();

        Logger bar = (Logger)LoggerFactory.getLogger("foo.bar");
        bar.setLevel(Level.DEBUG);
        Logger baz = (Logger)LoggerFactory.getLogger("foo.baz");
        baz.setLevel(Level.INFO);

        bar.debug("Test message");
        baz.debug("Test message"); // Would not be logged

        ref.debug("Test message ref");

        // One event should be logged.
        assertEquals(2, ta.events.size());
    }

    @Test
    public void appenderRestartPostReset() throws Exception{
        final TestAppender ta = registerAppender("ROOT");
        delay();

        assertTrue(ta.isStarted());
        final int stopCount = ta.stopCount;
        final int startCount = ta.startCount;

        eventAdmin.sendEvent(new Event(RESET_EVENT_TOPIC, (Dictionary)null));

        new RetryLoop(new RetryLoop.Condition() {
            @Override
            public String getDescription() {
                return "Stopcount not increased";
            }

            @Override
            public boolean isTrue() throws Exception {
                return ta.stopCount > stopCount && ta.startCount > startCount;
            }
        }, 10, 100);

        assertTrue(ta.isStarted());
    }

    @After
    public void unregisterAppender(){
        sr.unregister();
    }


    private TestAppender registerAppender(String... loggers){
        TestAppender ta = new TestAppender();
        Dictionary<String, Object> props = new Hashtable<String, Object>();
        props.put("loggers", loggers);
        sr = bundleContext.registerService(Appender.class.getName(), ta, props);
        delay();
        return ta;
    }


    private static class TestAppender extends AppenderBase<ILoggingEvent> {
        final List<ILoggingEvent> events = new ArrayList<ILoggingEvent>();
        final List<String> msgs = new ArrayList<String>();
        int stopCount;
        int startCount;

        @Override
        protected void append(ILoggingEvent eventObject) {
            events.add(eventObject);
            msgs.add(eventObject.getFormattedMessage());
        }

        @Override
        public String getName() {
            return "TestAppender";
        }

        public void reset(){
            events.clear();
            msgs.clear();
        }

        @Override
        public void stop() {
            super.stop();
            stopCount++;
        }

        @Override
        public void start() {
            super.start();
            startCount++;
        }
    }

}
