/*
 * 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.util.Assert;
import com.arsdigita.util.ResourceManager;
import com.arsdigita.util.WrappedError;
import com.arsdigita.xml.Document;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

/**
 *
 * A debugger that displays the original XML source of a document
 * prior to transformation (only applies if using Bebop JSP), the
 * generated XML document before transformation, and the XSL
 * stylesheet files used for transformation.
 *
 * To view a page using this debugger, pass "debug=transform" in as a
 * query variable.
 *
 * @see com.arsdigita.bebop.jsp.ShowPage
 *
 * @author Justin Ross &lt;<a href="mailto:jross@redhat.com">jross@redhat.com</a>&gt;
 * @version $Id: //core-platform/dev/src/com/arsdigita/web/TransformationDebugger.java#12 $
 */
public class TransformationDebugger extends Debugger {
    public static final String versionId =
        "$Id: //core-platform/dev/src/com/arsdigita/web/TransformationDebugger.java#12 $" +
        "$Author: dennis $" +
        "$DateTime: 2004/04/07 16:07:11 $";

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

    // private Document m_original;
    // private Document m_source;
    private URL m_sheet;
    private List m_dependents;

    /**
     * The value passed in to the "debug" query string that activates
     * this particular debugger.
     */
    public static final String TRANSFORM_DEBUG_VALUE = "transform";

    // Debuggers are per-request objects.
    /**
     * @pre sheet != null
     * @pre dependents != null
     **/
    public TransformationDebugger(Document original,
                                  Document source,
                                  URL sheet,
                                  List dependents) {
        Assert.exists(sheet, URL.class);
        Assert.exists(sheet, List.class);
        // m_original = original;
        // m_source = source;
        m_sheet = sheet;
        m_dependents = dependents;
    }

    /**
     * @see #TransformationDebugger(Document, Document, URL, List)
     **/
    public TransformationDebugger(URL sheet, List dependents) {
        this(null, null, sheet, dependents);
    }

    public boolean isRequested(HttpServletRequest sreq) {
        String value = sreq.getParameter(DEBUG_PARAMETER);

        return value != null && value.indexOf(TRANSFORM_DEBUG_VALUE) != -1;
    }

    public String debug() {
        StringBuffer buffer = new StringBuffer(1024);

        buffer.append("<h2>The Stylesheet files</h2>");
        buffer.append("<ul>");

        try {
            Iterator sources = m_dependents.iterator();

            File root = ResourceManager.getInstance().getWebappRoot();
            String base = root.toURL().toExternalForm();

            while (sources.hasNext()) {
                String path = sources.next().toString();

                if (path.startsWith(base)) {
                    path = path.substring(base.length());
                }

                buffer.append("<li><code><a href=\"" + path + "\">" + path +
                              "</a></code></li>");
            }
        } catch (IOException ioe) {
            throw new WrappedError(ioe);
        }

        buffer.append("</ul>");
        return buffer.toString();
    }

    protected String getStylesheetContents() {
        try {
            URLConnection con = m_sheet.openConnection();

            StringBuffer buffer = new StringBuffer();

            String contentType = con.getContentType();

            String encoding = "ISO-8859-1";
            int offset = (contentType == null ? -1 : contentType.indexOf("charset="));
            if (offset != -1) {
                encoding = contentType.substring(offset + 8).trim();
            }
            if (s_log.isDebugEnabled()) {
                s_log.debug("Received content type " + contentType);
            }
            InputStream is = con.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, encoding);
            if (s_log.isDebugEnabled()) {
                s_log.debug("Process with character encoding " + isr.getEncoding());
            }
            BufferedReader input = new BufferedReader(isr);

            String line;
            while ((line = input.readLine()) != null) {
                buffer.append(line).append('\n');
            }
            input.close();
            return buffer.toString();

        } catch (MalformedURLException ex) {
            ex.printStackTrace();
            return "Stylesheet contents unavailable: " + ex.getMessage();
        } catch (IOException ex) {
            ex.printStackTrace();
            return "Stylesheet contents unavailable: " + ex.getMessage();
        }
    }
}
