/*
 *  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.juli;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

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

/**
 * Test cases for {@link ClassLoaderLogManager}.
 */
public class TestClassLoaderLogManager {

    private static final byte[] EMPTY_BYTES = {};

    @Test
    public void testReplace() {
        ClassLoaderLogManager logManager = new ClassLoaderLogManager();
        Assert.assertEquals("", logManager.replace(""));
        Assert.assertEquals("${", logManager.replace("${"));
        Assert.assertEquals("${undefinedproperty}", logManager.replace("${undefinedproperty}"));
        Assert.assertEquals(
                System.lineSeparator() + File.pathSeparator + File.separator,
                logManager.replace("${line.separator}${path.separator}${file.separator}"));
        Assert.assertEquals(
                "foo" + File.separator + "bar" + System.lineSeparator() + File.pathSeparator + "baz",
                logManager.replace("foo${file.separator}bar${line.separator}${path.separator}baz"));
        // BZ 51249
        Assert.assertEquals(
                "%{file.separator}" + File.separator,
                logManager.replace("%{file.separator}${file.separator}"));
        Assert.assertEquals(
                File.separator + "${undefinedproperty}" + File.separator,
                logManager.replace("${file.separator}${undefinedproperty}${file.separator}"));
        Assert.assertEquals("${}" + File.pathSeparator, logManager.replace("${}${path.separator}"));
    }

    @Test
    public void testBug56082() {
        ClassLoaderLogManager logManager = new ClassLoaderLogManager();

        LoggerCreateThread[] createThreads = new LoggerCreateThread[10];
        for (int i = 0; i < createThreads.length; i ++) {
            createThreads[i] = new LoggerCreateThread(logManager);
            createThreads[i].setName("LoggerCreate-" + i);
            createThreads[i].start();
        }

        LoggerListThread listThread = new LoggerListThread(logManager);
        listThread.setName("LoggerList");
        listThread.start();

        try {
            listThread.join(2000);
        } catch (InterruptedException e) {
            // Ignore
        }

        for (LoggerCreateThread createThread : createThreads) {
            createThread.setRunning(false);
        }

        Assert.assertTrue(listThread.isRunning());
        listThread.setRunning(false);
    }

    /*
     * Tests if a per-app root logger has a not {@code null} level.
     */
    @Test
    public void testBug66184() throws IOException {
        final ClassLoader cl = new TestClassLoader();
        final Thread currentThread = Thread.currentThread();
        final ClassLoader oldCL = currentThread.getContextClassLoader();
        try {
            currentThread.setContextClassLoader(cl);
            final ClassLoaderLogManager logManager = new ClassLoaderLogManager();
            logManager.readConfiguration();
            final Logger rootLogger = logManager.getLogger("");
            Assert.assertNotNull("root logger is null", rootLogger);
            Assert.assertNull("root logger has a parent", rootLogger.getParent());
            Assert.assertEquals(Level.INFO, rootLogger.getLevel());
        } finally {
            currentThread.setContextClassLoader(oldCL);
        }
    }

    private static class LoggerCreateThread extends Thread {

        private final LogManager logManager;
        private volatile boolean running = true;

        LoggerCreateThread(LogManager logManager) {
            this.logManager = logManager;
        }

        @Override
        public void run() {
            Random r = new Random();
            while (running) {
                Logger logger = Logger.getLogger("Bug56082-" + r.nextInt(100000));
                logManager.addLogger(logger);
            }
        }

        public void setRunning(boolean running) {
            this.running = running;
        }
    }

    private static class LoggerListThread extends Thread {

        private final LogManager logManager;
        private volatile boolean running = true;

        LoggerListThread(LogManager logManager) {
            this.logManager = logManager;
        }

        @Override
        public void run() {
            while (running) {
                try {
                    Collections.list(logManager.getLoggerNames());
                } catch (Exception e) {
                    e.printStackTrace();
                    running = false;
                }
            }
        }

        public boolean isRunning() {
            return running;
        }

        public void setRunning(boolean running) {
            this.running = running;
        }
    }

    private static class TestClassLoader extends URLClassLoader implements WebappProperties {

        TestClassLoader() {
            super(new URL[0]);
        }


        @Override
        public String getWebappName() {
            return "webapp";
        }

        @Override
        public String getHostName() {
            return "localhost";
        }

        @Override
        public String getServiceName() {
            return "Catalina";
        }

        @Override
        public URL findResource(String name) {
            if ("logging.properties".equals(name)) {
                try {
                    return URI.create("file:///path/does/not/exist").toURL();
                } catch (MalformedURLException e) {
                    // Should never happen
                    throw new IllegalArgumentException(e);
                }
            }
            return null;
        }


        @Override
        public InputStream getResourceAsStream(final String resource) {
            if ("logging.properties".equals(resource)) {
                return new ByteArrayInputStream(EMPTY_BYTES);
            }
            return null;
        }
    }
}
