/*
 * Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.web;

import com.arsdigita.kernel.Kernel;
import java.util.ArrayList;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;

/**
 * Debugger contains static methods for registering debuggers.
 * Typically, debuggers are written to display the contents of
 * internal CCM data structures e.g., the XML representation of a page
 * prior to transformation. Subclass this class to add a particular
 * type of debugger.
 *
 * @see TransformationDebugger
 *
 * @author Justin Ross
 */
public abstract class Debugger {
    public static final String versionId =
        "$Id: //core-platform/dev/src/com/arsdigita/web/Debugger.java#9 $" +
        "$Author: dennis $" +
        "$DateTime: 2004/04/07 16:07:11 $";

    private static final Logger s_log = Logger.getLogger(Debugger.class);

    public static final String DEBUG_PARAMETER = "debug";
    public static final ThreadLocal s_debuggers = new DebuggerListLocal();

    public static class DebugParameterListener implements ParameterListener {
        public void run(HttpServletRequest sreq, ParameterMap map) {
            if (Kernel.getConfig().isDebugEnabled()) {
                final String value = sreq.getParameter(DEBUG_PARAMETER);

                if (value != null) {
                    map.setParameter(DEBUG_PARAMETER, value);
                }
            }
        }
    }

    public static final void addDebugger(Debugger debugger) {
        ArrayList list = (ArrayList) s_debuggers.get();
        list.add(debugger);
    }

    public static final String getDebugging(HttpServletRequest sreq) {
        ArrayList list = (ArrayList) s_debuggers.get();
        Iterator iter = list.iterator();
        StringBuffer buffer = new StringBuffer();

        while (iter.hasNext()) {
            Debugger debug = (Debugger) iter.next();

            if (debug.isRequested(sreq)) {
                buffer.append(debug.debug());
            }
        }

        return buffer.toString();
    }

    public abstract boolean isRequested(HttpServletRequest sreq);

    public abstract String debug();

    private static class DebuggerListLocal extends InternalRequestLocal {
        protected Object initialValue() {
            if (Kernel.getConfig().isDebugEnabled()) {
                return new ArrayList();
            } else {
                return null;
            }
        }

        protected void clearValue() {
            if (Kernel.getConfig().isDebugEnabled()) {
                ArrayList list = (ArrayList) get();
                list.clear();
            }
        }
    }
}

