package org.xbib.logging.ext.test.handlers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.xbib.logging.ExtHandler;
import org.xbib.logging.ExtLogRecord;
import org.xbib.logging.Level;
import org.xbib.logging.ext.handlers.QueueHandler;
import org.junit.jupiter.api.Test;
import org.xbib.logging.ext.test.AssertingErrorManager;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class QueueHandlerTests extends AbstractHandlerTest {

    public QueueHandlerTests() {
    }

    @Test
    public void testQueueSize() {
        try (QueueHandler handler = new QueueHandler(5)) {
            handler.setErrorManager(AssertingErrorManager.of());
            // Log 6 records and ensure only 5 are available
            for (int i = 0; i < 6; i++) {
                handler.publish(createLogRecord("Test message %d", i));
            }
            final ExtLogRecord[] records = handler.getQueue();
            assertEquals(5, records.length, "QueueHandler held onto more records than allowed");
            // Check each message, the last should be the sixth
            assertEquals("Test message 1", records[0].getMessage());
            assertEquals("Test message 2", records[1].getMessage());
            assertEquals("Test message 3", records[2].getMessage());
            assertEquals("Test message 4", records[3].getMessage());
            assertEquals("Test message 5", records[4].getMessage());
        }
    }

    @Test
    public void testNestedHandlers() throws Exception {
        // Create a nested a handler
        final NestedHandler nestedHandler = new NestedHandler();
        nestedHandler.setLevel(Level.INFO);

        try (QueueHandler handler = new QueueHandler(10)) {
            handler.setErrorManager(AssertingErrorManager.of());
            handler.setLevel(Level.ERROR);
            handler.addHandler(nestedHandler);

            // Log an info messages
            handler.publish(createLogRecord(Level.INFO, "Test message"));
            assertEquals(1, nestedHandler.getRecords().size());
            assertEquals(0, handler.getQueue().length);

            // Log a warn messages
            handler.publish(createLogRecord(Level.WARN, "Test message"));
            assertEquals(2, nestedHandler.getRecords().size());
            assertEquals(0, handler.getQueue().length);

            // Log an error messages
            handler.publish(createLogRecord(Level.ERROR, "Test message"));
            assertEquals(3, nestedHandler.getRecords().size());
            assertEquals(1, handler.getQueue().length);
        }
    }

    static class NestedHandler extends ExtHandler {
        private final List<ExtLogRecord> records = new ArrayList<>();

        NestedHandler() {
            setErrorManager(AssertingErrorManager.of());
        }

        @Override
        protected void doPublish(final ExtLogRecord record) {
            records.add(record);
            super.doPublish(record);
        }

        Collection<ExtLogRecord> getRecords() {
            return Collections.unmodifiableCollection(records);
        }
    }
}
