
package uk.co.wingpath.util;

import java.util.*;

/**
* This class implements of the {@link Reporter} interface by buffering
* all messages. The messages can later be dumped to another reporter.
* This reporter is intended to be used at program startup, before proper
* reporting (e.g. to a GUI or file) has been set up.
*/

public class BufferReporter
    implements Reporter
{
    private static class Entry
    {
        final Reporter.Level level;
        final String helpId;
        final Throwable t;
        final String fmt;
        final Object [] args;

        private Entry (Reporter.Level level, String helpId,
            Throwable t, String fmt, Object [] args)
        {
            this.level = level;
            this.helpId = helpId;
            this.t = t;
            this.fmt = fmt;
            this.args = args;
        }
    }

    private ArrayList<Entry> entries;

    public BufferReporter ()
    {
        entries = new ArrayList<Entry> ();
    }

    public void dump (Reporter reporter)
    {
        for (Entry entry : entries)
        {
            switch (entry.level)
            {
            case FATAL:
                if (entry.t == null)
                    reporter.fatal (entry.fmt, entry.args);
                else
                    reporter.fatal (entry.t, entry.fmt, entry.args);
                break;

            case ERROR:
                reporter.error (entry.helpId, entry.fmt, entry.args);
                break;

            case WARN:
                reporter.warn (entry.helpId, entry.fmt, entry.args);
                break;

            case INFO:
                reporter.info (entry.helpId, entry.fmt, entry.args);
                break;

            case TRACE:
                reporter.trace (entry.helpId, entry.fmt, entry.args);
                break;

            case DEBUG:
                reporter.debug (entry.fmt, entry.args);
                break;
            }
        }
    }

    private void buffer (Reporter.Level level, String helpId,
        Throwable t, String fmt, Object [] args)
    {
        entries.add (new Entry (level, helpId, t, fmt, args));
    }

    @Override
    public boolean fatal (String fmt, Object... args)
    {
        buffer (Reporter.Level.FATAL, null, null, fmt, args);
        return true;
    }

    @Override
    public boolean fatal (Throwable t, String fmt, Object... args)
    {
        buffer (Reporter.Level.FATAL, null, t, fmt, args);
        return true;
    }

    @Override
    public void error (String helpId, String fmt, Object... args)
    {
        buffer (Reporter.Level.ERROR, helpId, null, fmt, args);
    }

    @Override
    public void warn (String helpId, String fmt, Object... args)
    {
        buffer (Reporter.Level.WARN, helpId, null, fmt, args);
    }

    @Override
    public void info (String helpId, String fmt, Object... args)
    {
        buffer (Reporter.Level.INFO, helpId, null, fmt, args);
    }

    @Override
    public void trace (String helpId, String fmt, Object... args)
    {
        buffer (Reporter.Level.TRACE, helpId, null, fmt, args);
    }

    @Override
    public boolean debug (String fmt, Object... args)
    {
        buffer (Reporter.Level.DEBUG, null, null, fmt, args);
        return true;
    }

    @Override
    public void clear ()
    {
        entries.clear ();
    }
}

