/**
 * 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.assertArrayEquals;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.ErrorManager;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;

import org.junit.Before;
import org.ow2.petals.log.AbstractConfLog;
import org.ow2.petals.log.LogRecordHelper;

import com.ebmwebsourcing.easycommons.properties.PropertiesException;
import com.ebmwebsourcing.easycommons.thread.ExecutionContext;

public abstract class AbstractTestPetalsFileHandler extends AbstractConfLog {

    @Before
    public void before() {
        super.before();
        ExecutionContext.getProperties().clear();
    }

    protected static final void compareLogRecordsWithFormattedLogRecords(
            final List<LogRecord> expectedLogRecords, final List<String> formattedLogRecords) {
        final String[] expectedFormattedLogRecords = new String[expectedLogRecords.size()];
        final SimpleFormatter sf = new SimpleFormatter();
        for (int i = 0; i < expectedLogRecords.size(); ++i) {
            expectedFormattedLogRecords[i] = sf.format(expectedLogRecords.get(i));
        }
        assertArrayEquals(expectedFormattedLogRecords,
                formattedLogRecords.toArray(new String[formattedLogRecords.size()]));
    }

    protected static final List<LogRecord> createTestLogRecords(final String[] logMessages) {
        final List<LogRecord> expectedLogRecords = new ArrayList<LogRecord>();
        for (final String logMessage : logMessages) {
            LogRecord lr = LogRecordHelper.newLogRecord(Level.SEVERE, logMessage, 0);
            expectedLogRecords.add(lr);
        }
        return Collections.unmodifiableList(expectedLogRecords);
    }

    protected static final List<LogRecord> createTestLogRecords(final String[] logMessages,
            Level level) {
        final List<LogRecord> expectedLogRecords = new ArrayList<LogRecord>();
        for (final String logMessage : logMessages) {
            LogRecord lr = LogRecordHelper.newLogRecord(level, logMessage, 0);
            expectedLogRecords.add(lr);
        }
        return Collections.unmodifiableList(expectedLogRecords);
    }

    protected static final void testPublishRecords(final Handler pfh,
            final List<LogRecord> logRecordsToPublish, final File expectedOutputFile,
            final List<LogRecord> expectedLogRecords) throws IOException {

        for (final LogRecord lr : logRecordsToPublish) {
            pfh.publish(lr);
        }

        compareLogRecordsWithFormattedLogRecords(expectedLogRecords,
                parseFormattedRecords(expectedOutputFile));
    }

    protected static final List<String> parseFormattedRecords(File file) throws IOException {
        assert file != null;

        // This implementation is dirty because it supposes a log record
        // formatted by a java.util.logging.SimpleFormatter takes 2 lines

        List<String> records = new ArrayList<String>();

        String strLine = null;
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

            strLine = br.readLine();
            while (strLine != null) {
                final String recordLine1 = strLine;
                final String recordLine2 = br.readLine();
                assert recordLine2 != null : "A log record formatted by a java.util.logging.SimpleFormatter takes 2 lines.";
                records.add(String.format("%s%n%s%n", recordLine1, recordLine2));
                strLine = br.readLine();
            }
        } finally {
            if (br != null) {
                br.close();
            }
        }

        return Collections.unmodifiableList(records);
    }

    protected PetalsPayloadDumperFileHandler createLogHandler(final List<String> reportedErrors) throws IOException,
            PropertiesException {
        final PetalsPayloadDumperFileHandler handler = new PetalsPayloadDumperFileHandler();
        handler.setErrorManager(new ErrorManager() {
            @Override
            public synchronized void error(String msg, Exception ex, int code) {
                reportedErrors.add(msg);
            }
        });
        return handler;
    }

}
