/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.internal.runtime;

import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;

import java.io.PrintWriter;
import jdk.nashorn.internal.parser.Token;

/**
 * Handles JavaScript error reporting.
 */
public class ErrorManager {
    // TODO - collect and sort/collapse error messages.
    // TODO - property based error messages.
    /** Reporting writer. */
    private final PrintWriter writer;

    /** Error count. */
    private int errors;

    /** Warning count */
    private int warnings;

    /** Limit of the number of messages. */
    private int limit;

    /** Treat warnings as errors. */
    private boolean warningsAsErrors;

    /**
     * Constructor
     */
    public ErrorManager() {
        this(new PrintWriter(System.err, true)); //bootstrapping, context may not be initialized
    }

    /**
     * Constructor.
     * @param writer I/O writer to report on.
     */
    public ErrorManager(final PrintWriter writer) {
        this.writer           = writer;
        this.limit            = 100;
        this.warningsAsErrors = false;
    }

    /**
     * Check to see if number of errors exceed limit.
     */
    private void checkLimit() {
        int count = errors;

        if (warningsAsErrors) {
            count += warnings;
        }

        if (limit != 0 && count > limit) {
            throw rangeError("too.many.errors", Integer.toString(limit));
        }
    }

    /**
     * Format an error message to include source and line information.
     * @param message Error message string.
     * @param source  Source file information.
     * @param line    Source line number.
     * @param column  Source column number.
     * @param token   Offending token descriptor.
     * @return formatted string
     */
    public static String format(final String message, final Source source, final int line, final int column, final long token) {
        final String        eoln     = System.lineSeparator();
        final int           position = Token.descPosition(token);
        final StringBuilder sb       = new StringBuilder();

        // Source description and message.
        sb.append(source.getName()).
            append(':').
            append(line).
            append(':').
            append(column).
            append(' ').
            append(message).
            append(eoln);

        // Source content.
        final String sourceLine = source.getSourceLine(position);
        sb.append(sourceLine).append(eoln);

        // Pointer to column.
        for (int i = 0; i < column; i++) {
            if (i < sourceLine.length() && sourceLine.charAt(i) == '\t') {
                sb.append('\t');
            } else {
                sb.append(' ');
            }
        }

        sb.append('^');
        // Use will append eoln.
        // buffer.append(eoln);

        return sb.toString();
    }

    /**
     * Report an error using information provided by the ParserException
     *
     * @param e ParserException object
     */

    public void error(final ParserException e) {
        error(e.getMessage());
    }

    /**
     * Report an error message provided
     *
     * @param message Error message string.
     */
    public void error(final String message) {
        writer.println(message);
        writer.flush();
        errors++;
        checkLimit();
    }

    /**
     * Report a warning using information provided by the ParserException
     *
     * @param e ParserException object
     */
    public void warning(final ParserException e) {
        warning(e.getMessage());
    }

    /**
     * Report a warning message provided
     *
     * @param message Error message string.
     */
    public void warning(final String message) {
        writer.println(message);
        writer.flush();
        warnings++;
        checkLimit();
    }

    /**
     * Test to see if errors have occurred.
     * @return True if errors.
     */
    public boolean hasErrors() {
        return errors != 0;
    }

    /**
     * Get the message limit
     * @return max number of messages
     */
    public int getLimit() {
        return limit;
    }

    /**
     * Set the message limit
     * @param limit max number of messages
     */
    public void setLimit(final int limit) {
        this.limit = limit;
    }

    /**
     * Check whether warnings should be treated like errors
     * @return true if warnings should be treated like errors
     */
    public boolean isWarningsAsErrors() {
        return warningsAsErrors;
    }

    /**
     * Set warnings to be treated as errors
     * @param warningsAsErrors true if warnings should be treated as errors, false otherwise
     */
    public void setWarningsAsErrors(final boolean warningsAsErrors) {
        this.warningsAsErrors = warningsAsErrors;
    }

    /**
     * Get the number of errors
     * @return number of errors
     */
    public int getNumberOfErrors() {
        return errors;
    }

    /**
     * Get number of warnings
     * @return number of warnings
     */
    public int getNumberOfWarnings() {
        return warnings;
    }

    /**
     * Clear warnings and error count.
     */
    void reset() {
        warnings = 0;
        errors = 0;
    }
}
