/*
 * 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.logging.log4j.core.appender.rolling;

import static org.apache.logging.log4j.hamcrest.Descriptors.that;
import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.hasItemInArray;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;

import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorInputStream;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.util.Closer;
import org.apache.logging.log4j.junit.LoggerContextRule;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

/**
 *
 */
@RunWith(Parameterized.class)
public class RollingAppenderSizeTest {

    @Rule
    public RuleChain chain;

    private static final String DIR = "target/rolling1";

    private final String fileExtension;

    private Logger logger;

    private final boolean createOnDemand;

    @Parameterized.Parameters(name = "{0} \u2192 {1} (createOnDemand = {2})")
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] { //
                // @formatter:off
               {"log4j-rolling-gz-lazy.xml", ".gz", true},
               {"log4j-rolling-gz.xml", ".gz", false},
               {"log4j-rolling-numbered-gz.xml", ".gz", false},
               {"log4j-rolling-zip-lazy.xml", ".zip", true},
               {"log4j-rolling-zip.xml", ".zip", false},
                // Apache Commons Compress
               {"log4j-rolling-bzip2-lazy.xml", ".bz2", true},
               {"log4j-rolling-bzip2.xml", ".bz2", false},
               {"log4j-rolling-deflate-lazy.xml", ".deflate", true},
               {"log4j-rolling-deflate.xml", ".deflate", false},
               {"log4j-rolling-pack200-lazy.xml", ".pack200", true},
               {"log4j-rolling-pack200.xml", ".pack200", false},
               {"log4j-rolling-xz-lazy.xml", ".xz", true},
               {"log4j-rolling-xz.xml", ".xz", false},
                });
                // @formatter:on
    }

    private final LoggerContextRule loggerContextRule;

    public RollingAppenderSizeTest(final String configFile, final String fileExtension, final boolean createOnDemand) {
        this.fileExtension = fileExtension;
        this.createOnDemand = createOnDemand;
        this.loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(configFile);
        this.chain = loggerContextRule.withCleanFoldersRule(DIR);
    }

    @Before
    public void setUp() throws Exception {
        this.logger = this.loggerContextRule.getLogger(RollingAppenderSizeTest.class.getName());
    }

    @Test
    public void testIsCreateOnDemand() {
        final RollingFileAppender rfAppender = loggerContextRule.getRequiredAppender("RollingFile",
                RollingFileAppender.class);
        final RollingFileManager manager = rfAppender.getManager();
        Assert.assertNotNull(manager);
        Assert.assertEquals(createOnDemand, manager.isCreateOnDemand());
    }

    @Test
    public void testAppender() throws Exception {
        final Path path = Paths.get(DIR, "rollingtest.log");
        if (Files.exists(path) && createOnDemand) {
            Assert.fail(String.format("Unexpected file: %s (%s bytes)", path, Files.getAttribute(path, "size")));
        }
        for (int i = 0; i < 500; ++i) {
            logger.debug("This is test message number " + i);
        }
        try {
            Thread.sleep(100);
        } catch (final InterruptedException ie) {
            // Ignore the error.
        }

        final File dir = new File(DIR);
        assertTrue("Directory not created", dir.exists() && dir.listFiles().length > 0);
        final File[] files = dir.listFiles();
        assertNotNull(files);
        assertThat(files, hasItemInArray(that(hasName(that(endsWith(fileExtension))))));

        final FileExtension ext = FileExtension.lookup(fileExtension);
        if (ext == null || FileExtension.ZIP == ext || FileExtension.PACK200 == ext) {
            return; // Apache Commons Compress cannot deflate zip? TODO test decompressing these formats
        }
        // Stop the context to make sure all files are compressed and closed. Trying to remedy failures in CI builds.
        if (!loggerContextRule.getLoggerContext().stop(30, TimeUnit.SECONDS)) {
            System.err.println("Could not stop cleanly " + loggerContextRule + " for " + this);
        }
        for (final File file : files) {
            if (file.getName().endsWith(fileExtension)) {
                CompressorInputStream in = null;
                try (FileInputStream fis = new FileInputStream(file)) {
                    try {
                        in = new CompressorStreamFactory().createCompressorInputStream(ext.name().toLowerCase(), fis);
                    } catch (final CompressorException ce) {
                        ce.printStackTrace();
                        fail("Error creating input stream from " + file.toString() + ": " + ce.getMessage());
                    }
                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    assertNotNull("No input stream for " + file.getName(), in);
                    try {
                        IOUtils.copy(in, baos);
                    } catch (final Exception ex) {
                        ex.printStackTrace();
                        fail("Unable to decompress " + file.getAbsolutePath());
                    }
                    final String text = new String(baos.toByteArray(), Charset.defaultCharset());
                    final String[] lines = text.split("[\\r\\n]+");
                    for (final String line : lines) {
                        assertTrue(line.contains(
                                "DEBUG o.a.l.l.c.a.r.RollingAppenderSizeTest [main] This is test message number"));
                    }
                } finally {
                    Closer.close(in);
                }
            }
        }
    }
}
