/*
 * 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-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 intput 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);
                }
            }
        }
    }
}
