/**
 * Copyright (c) 2010-2012 EBM WebSourcing, 2012-2015 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see <http://www.gnu.org/licenses/>
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.log.handler;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.ErrorManager;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;

import org.apache.commons.lang.SystemUtils;
import org.junit.Before;
import org.junit.Test;
import org.ow2.petals.commons.log.PetalsExecutionContext;

import com.ebmwebsourcing.easycommons.thread.ExecutionContext;

/**
 * Unit tests of {@link PetalsFileHandler} that runs only on Linux, mainly because we are unable to create restricted
 * folder
 * 
 * @author Christophe DENEUX - Linagora
 */
public class PetalsFileHandlerLinuxOnlyTest extends AbstractTestPetalsFileHandler {

    @Before
    public void linuxOnly() {
        org.junit.Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
    }

    /**
     * Check the generation of a log trace into a not write log file.
     */
    @Test
    public void testPublishWithNotWritableLogFilePath() throws Exception {

        final File temporaryRootDir = this.tempFolder.newFolder("root");
        System.setProperty(PetalsFileHandler.PETALS_LOG_DIR_PROPERTY_NAME,
                temporaryRootDir.getCanonicalPath());

        final LogManager manager = LogManager.getLogManager();
        final InputStream is = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("logConf.properties");
        try {
            assertNotNull("Log file configuration not found", is);
            manager.readConfiguration(is);
        } finally {
            is.close();
        }

        final PrintStream standardConsoleError = System.err;
        try {
            final ByteArrayOutputStream errBAIS = new ByteArrayOutputStream();
            System.setErr(new PrintStream(errBAIS));

            final PetalsFileHandler pfh = new PetalsFileHandler();

            final String error = errBAIS.toString();
            assertTrue("An error occurs", error.isEmpty());
            assertSame(Level.FINEST, pfh.getLevel());
            final File expectedBaseDir = new File(temporaryRootDir, BASEDIR_DEFAULT_TEST_VALUE);
            assertEquals(expectedBaseDir.getCanonicalPath(), pfh.basedir.getCanonicalPath());
            final File expectedFlowsSubDir = new File(new File(temporaryRootDir,
                    BASEDIR_DEFAULT_TEST_VALUE), FLOWSUBDIR_DEFAULT_TEST_VALUE);
            assertEquals(expectedFlowsSubDir.getCanonicalPath(), pfh.flowsSubdir.getCanonicalPath());
            assertEquals(LOGFILENAME_DEFAULT_TEST_VALUE, pfh.logfilename);
            assertEquals(SimpleFormatter.class, pfh.getFormatter().getClass());

            PetalsExecutionContext.initFlowInstanceId();
            final File expectedLogFile = new File(new File(expectedFlowsSubDir, ExecutionContext
                    .getProperties().getProperty(
                            PetalsExecutionContext.FLOW_INSTANCE_ID_PROPERTY_NAME)),
                    LOGFILENAME_DEFAULT_TEST_VALUE);

            testPublishRecords(pfh, createTestLogRecords(new String[] { "testMessage1" }),
                    expectedLogFile, createTestLogRecords(new String[] { "testMessage1" }));

            expectedFlowsSubDir.setExecutable(false);
            expectedFlowsSubDir.setWritable(false);

            testPublishWithReportedError(pfh);

        } finally {
            PetalsExecutionContext.clear();
            System.setErr(standardConsoleError);
            System.clearProperty(PetalsFileHandler.PETALS_LOG_DIR_PROPERTY_NAME);
        }
    }

    private void testPublishWithReportedError(final PetalsFileHandler pfh) {

        final LogRecord lr = new LogRecord(Level.SEVERE, "testMessage1");

        final List<String> reportedErrors = new ArrayList<String>();
        pfh.setErrorManager(new ErrorManager() {
            @Override
            public synchronized void error(String msg, Exception ex, int code) {
                reportedErrors.add(msg == null ? ex.getMessage() : msg);
            }
        });

        pfh.publish(lr);
        assertEquals(1, reportedErrors.size());
    }
}
