/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.struts2.jasper.compiler;

import org.apache.struts2.jasper.JspCompilationContext;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Class providing details about a javac compilation error.
 *
 * @author Jan Luehe
 * @author Kin-man Chung
 */
public class JavacErrorDetail {

    private String javaFileName;
    private int javaLineNum;
    private String jspFileName;
    private int jspBeginLineNum;
    private StringBuffer errMsg;
    private String jspExtract = null;

    /**
     * Constructor.
     *
     * @param javaFileName The name of the Java file in which the
     *                     compilation error occurred
     * @param javaLineNum  The compilation error line number
     * @param errMsg       The compilation error message
     */
    public JavacErrorDetail(String javaFileName,
                            int javaLineNum,
                            StringBuffer errMsg) {

        this.javaFileName = javaFileName;
        this.javaLineNum = javaLineNum;
        this.errMsg = errMsg;
        this.jspBeginLineNum = -1;
    }

    /**
     * Constructor.
     *
     * @param javaFileName    The name of the Java file in which the
     *                        compilation error occurred
     * @param javaLineNum     The compilation error line number
     * @param jspFileName     The name of the JSP file from which the Java source
     *                        file was generated
     * @param jspBeginLineNum The start line number of the JSP element
     *                        responsible for the compilation error
     * @param errMsg          The compilation error message
     */
    public JavacErrorDetail(String javaFileName,
                            int javaLineNum,
                            String jspFileName,
                            int jspBeginLineNum,
                            StringBuffer errMsg) {

        this(javaFileName, javaLineNum, jspFileName, jspBeginLineNum, errMsg,
                null);
    }

    public JavacErrorDetail(String javaFileName,
                            int javaLineNum,
                            String jspFileName,
                            int jspBeginLineNum,
                            StringBuffer errMsg,
                            JspCompilationContext ctxt) {
        this(javaFileName, javaLineNum, errMsg);
        this.jspFileName = jspFileName;
        this.jspBeginLineNum = jspBeginLineNum;

        if (jspBeginLineNum > 0 && ctxt != null) {
            InputStream is = null;
            FileInputStream fis = null;
            try {
                // Read both files in, so we can inspect them
                is = ctxt.getResourceAsStream(jspFileName);
                String[] jspLines = readFile(is);

                fis = new FileInputStream(ctxt.getServletJavaFileName());
                String[] javaLines = readFile(fis);

                // If the line contains the opening of a multi-line scriptlet
                // block, then the JSP line number we got back is probably
                // faulty.  Scan forward to match the java line...
                if (jspLines[jspBeginLineNum - 1].lastIndexOf("<%") >
                        jspLines[jspBeginLineNum - 1].lastIndexOf("%>")) {
                    String javaLine = javaLines[javaLineNum - 1].trim();

                    for (int i = jspBeginLineNum - 1; i < jspLines.length; i++) {
                        if (jspLines[i].indexOf(javaLine) != -1) {
                            // Update jsp line number
                            this.jspBeginLineNum = i + 1;
                            break;
                        }
                    }
                }

                // copy out a fragment of JSP to display to the user
                StringBuffer fragment = new StringBuffer(1024);
                int startIndex = Math.max(0, this.jspBeginLineNum - 1 - 3);
                int endIndex = Math.min(
                        jspLines.length - 1, this.jspBeginLineNum - 1 + 3);

                for (int i = startIndex; i <= endIndex; ++i) {
                    fragment.append(i + 1);
                    fragment.append(": ");
                    fragment.append(jspLines[i]);
                    fragment.append("\n");
                }
                jspExtract = fragment.toString();

            } catch (IOException ioe) {
                // Can't read files - ignore
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException ioe) {
                        // Ignore
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException ioe) {
                        // Ignore
                    }
                }
            }
        }

    }

    /**
     * Gets the name of the Java source file in which the compilation error
     * occurred.
     *
     * @return Java source file name
     */
    public String getJavaFileName() {
        return this.javaFileName;
    }

    /**
     * Gets the compilation error line number.
     *
     * @return Compilation error line number
     */
    public int getJavaLineNumber() {
        return this.javaLineNum;
    }

    /**
     * Gets the name of the JSP file from which the Java source file was
     * generated.
     *
     * @return JSP file from which the Java source file was generated.
     */
    public String getJspFileName() {
        return this.jspFileName;
    }

    /**
     * Gets the start line number (in the JSP file) of the JSP element
     * responsible for the compilation error.
     *
     * @return Start line number of the JSP element responsible for the
     *         compilation error
     */
    public int getJspBeginLineNumber() {
        return this.jspBeginLineNum;
    }

    /**
     * Gets the compilation error message.
     *
     * @return Compilation error message
     */
    public String getErrorMessage() {
        return this.errMsg.toString();
    }

    /**
     * Gets the extract of the JSP that corresponds to this message.
     *
     * @return Extract of JSP where error occurred
     */
    public String getJspExtract() {
        return this.jspExtract;
    }

    /**
     * Reads a text file from an input stream into a String[]. Used to read in
     * the JSP and generated Java file when generating error messages.
     */
    private String[] readFile(InputStream s) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(s));
        List lines = new ArrayList();
        String line;

        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }

        return (String[]) lines.toArray(new String[lines.size()]);
    }
}
