/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.xmlbeans;

import javax.xml.stream.Location;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

/**
 * Represents a message at a specific XML location.
 * <p>
 * The message can be an error, warning, or simple information, and
 * it may optionally be associated with a specific location in
 * an XML document.  The class includes methods for extracting
 * the location as a line number, XmlCursor, or XmlObject, as
 * well as for obtaining and message and severity of the
 * error.
 *
 * @see XmlOptions#setErrorListener
 * @see XmlException
 */
public class XmlError implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    private static final ResourceBundle _bundle = PropertyResourceBundle.getBundle("org.apache.xmlbeans.message", Locale.ROOT);

    private final String _message;
    private final String _code;
    private final String _source;
    private final int _severity;
    private final int _line;
    private final int _column;
    private int _offset = -1;

    private transient XmlCursor _cursor;

    /**
     * Copy constructor.
     *
     * @param src The original XmlError to copy.
     */
    public XmlError(XmlError src) {
        _message = src.getMessage();
        _code = src.getErrorCode();
        _severity = src.getSeverity();
        _source = src.getSourceName();
        _line = src.getLine();
        _column = src.getColumn();
        _offset = src.getOffset();
        _cursor = src.getCursorLocation();
    }

    /**
     * The static factory methods should be used instead of
     * this constructor.
     */
    private XmlError(String message, String code, int severity,
                     String source, int line, int column, int offset, XmlCursor cursor) {
        _message = message;
        _code = code;
        _severity = severity;
        _source = source;
        _line = line;
        _column = column;
        _offset = offset;
        _cursor = cursor;
    }

    private XmlError(String code, Object[] args, int severity,
                     String source, int line, int column, int offset, XmlCursor cursor) {
        this(XmlError.formattedMessage(code, args), code, severity, source, line, column, offset, cursor);
    }

    /**
     * The static factory methods should be used instead of
     * this constructor.
     */
    protected XmlError(String message, String code, int severity, XmlCursor cursor) {
        String source = null;
        int line = -1;
        int column = -1;
        int offset = -1;

        if (cursor != null) {
            // Hunt down the line/column/offset
            source = cursor.documentProperties().getSourceName();

            try (XmlCursor c = cursor.newCursor()) {
                XmlLineNumber ln =
                    (XmlLineNumber) c.getBookmark(XmlLineNumber.class);

                if (ln == null) {
                    ln = (XmlLineNumber) c.toPrevBookmark(XmlLineNumber.class);
                }

                if (ln != null) {
                    line = ln.getLine();
                    column = ln.getColumn();
                    offset = ln.getOffset();
                }
            }
        }

        _message = message;
        _code = code;
        _severity = severity;
        _source = source;
        _line = line;
        _column = column;
        _offset = offset;
        _cursor = cursor;
    }

    protected XmlError(String code, Object[] args, int severity, XmlCursor cursor) {
        this(XmlError.formattedMessage(code, args), code, severity, cursor);
    }

    /**
     * The static factory methods should be used instead of
     * this constructor.
     */
    protected XmlError(String message, String code, int severity, Location loc) {
        String source = null;
        int line = -1;
        int column = -1;

        if (loc != null) {
            line = loc.getLineNumber();
            column = loc.getColumnNumber();
            source = loc.getPublicId();
            if (source == null) {
                source = loc.getSystemId();
            }
        }

        _message = message;
        _code = code;
        _severity = severity;
        _source = source;
        _line = line;
        _column = column;
    }

    protected XmlError(String code, Object[] args, int severity, Location loc) {
        this(XmlError.formattedMessage(code, args), code, severity, loc);
    }

    /**
     * Returns an XmlError for the given message, with no location and {@link #SEVERITY_ERROR}.
     *
     * @param message the error message
     */
    public static XmlError forMessage(String message) {
        return forMessage(message, SEVERITY_ERROR);
    }

    /**
     * Returns an XmlError for the given message, with no location and the given severity.
     *
     * @param message  the error message
     * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     */
    public static XmlError forMessage(String message, int severity) {
        return forSource(message, severity, null);
    }

    /**
     * Returns an XmlError for the given message, with no location and the given severity.
     *
     * @param code the error code
     * @param args the arguments to use in formatting the error message
     */
    public static XmlError forMessage(String code, Object[] args) {
        return forSource(code, args, SEVERITY_ERROR, null);
    }

    /**
     * Returns an XmlError for the given message, with no location and the given severity.
     *
     * @param code     the error code
     * @param args     the arguments to use in formatting the error message
     * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     */
    public static XmlError forMessage(String code, Object[] args, int severity) {
        return forSource(code, args, severity, null);
    }

    /**
     * Returns an XmlError for the given message, located in the given file and {@link #SEVERITY_ERROR}.
     *
     * @param message    the error message
     * @param sourceName the URL or other name for the file
     */
    public static XmlError forSource(String message, String sourceName) {
        return forLocation(message, SEVERITY_ERROR, sourceName, -1, -1, -1);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located in the given file.
     *
     * @param message    the error message
     * @param severity   the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param sourceName the URL or other name for the file
     */
    public static XmlError forSource(String message, int severity, String sourceName) {
        return forLocation(message, severity, sourceName, -1, -1, -1);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located in the given file.
     *
     * @param code       the error code
     * @param args       the arguments to use in formatting the error message
     * @param severity   the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param sourceName the URL or other name for the file
     */
    public static XmlError forSource(String code, Object[] args, int severity, String sourceName) {
        return forLocation(code, args, severity, sourceName, -1, -1, -1);
    }

    /**
     * Returns an XmlError for the given message, located at a specific point in the given file and {@link #SEVERITY_ERROR}.
     *
     * @param message    the error message
     * @param sourceName the URL or other name for the file
     * @param location   the location from an xml stream
     */
    public static XmlError forLocation(String message, String sourceName, Location location) {
        return new XmlError(message, (String) null, SEVERITY_ERROR, sourceName,
            location.getLineNumber(), location.getColumnNumber(), -1, null);
    }

    /**
     * Returns an XmlError for the given message, located at a specific point in the given file and {@link #SEVERITY_ERROR}.
     *
     * @param message    the error message
     * @param sourceName the URL or other name for the file
     * @param line       the 1-based line number, or -1 if not known
     * @param column     the 1-based column number, or -1 if not known
     * @param offset     the 0-base file character offset, or -1 if not known
     */
    public static XmlError forLocation(String message, String sourceName, int line, int column, int offset) {
        return new XmlError(message, (String) null, SEVERITY_ERROR, sourceName, line, column, offset, null);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located at a specific point in the given file.
     *
     * @param code       the error code
     * @param args       the arguments to use in formatting the error message
     * @param severity   the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param sourceName the URL or other name for the file
     * @param line       the 1-based line number, or -1 if not known
     * @param column     the 1-based column number, or -1 if not known
     * @param offset     the 0-base file character offset, or -1 if not known
     */
    public static XmlError forLocation(String code, Object[] args, int severity, String sourceName, int line, int column, int offset) {
        return new XmlError(code, args, severity, sourceName, line, column, offset, null);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located at a specific point in the given file.
     *
     * @param message    the error message
     * @param severity   the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param sourceName the URL or other name for the file
     * @param line       the 1-based line number, or -1 if not known
     * @param column     the 1-based column number, or -1 if not known
     * @param offset     the 0-base file character offset, or -1 if not known
     */
    public static XmlError forLocation(String message, int severity, String sourceName, int line, int column, int offset) {
        return new XmlError(message, (String) null, severity, sourceName, line, column, offset, null);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located at the given physcial location and XmlCursor.
     *
     * @param message    the error message
     * @param severity   the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param sourceName the URL or other name for the file
     * @param line       the 1-based line number, or -1 if not known
     * @param column     the 1-based column number, or -1 if not known
     * @param offset     the 0-base file character offset, or -1 if not known
     * @param cursor     the XmlCursor representing the location of the error
     */
    public static XmlError forLocationAndCursor(String message, int severity, String sourceName, int line, int column, int offset, XmlCursor cursor) {
        return new XmlError(message, (String) null, severity, sourceName, line, column, offset, cursor);
    }

    /**
     * Returns an XmlError for the given message, located at the XmlObject, with {@link #SEVERITY_ERROR}.
     *
     * @param message the error message
     * @param xobj    the XmlObject representing the location of the error
     */
    public static XmlError forObject(String message, XmlObject xobj) {
        return forObject(message, SEVERITY_ERROR, xobj);
    }

    /**
     * Returns an XmlError for the given message, located at the XmlObject, with {@link #SEVERITY_ERROR}.
     *
     * @param code the error code
     * @param args the arguments to use in formatting the error message
     * @param xobj the XmlObject representing the location of the error
     */
    public static XmlError forObject(String code, Object[] args, XmlObject xobj) {
        return forObject(code, args, SEVERITY_ERROR, xobj);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located at the XmlObject.
     *
     * @param message  the error message
     * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param xobj     the XmlObject representing the location of the error
     */
    public static XmlError forObject(String message, int severity, XmlObject xobj) {
        if (xobj == null) {
            return forMessage(message, severity);
        }

        XmlCursor cur = xobj.newCursor();
        return forCursor(message, severity, cur);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located at the XmlObject.
     *
     * @param code     the error code
     * @param args     the arguments to use in formatting the error message
     * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param xobj     the XmlObject representing the location of the error
     */
    public static XmlError forObject(String code, Object[] args, int severity, XmlObject xobj) {
        if (xobj == null) {
            return forMessage(code, args, severity);
        }

        XmlCursor cur = xobj.newCursor();
        return forCursor(code, args, severity, cur);
    }

    /**
     * Returns an XmlError for the given message, located at the XmlCursor, with {@link #SEVERITY_ERROR}.
     *
     * @param message the error message
     * @param cursor  the XmlCursor representing the location of the error
     */
    public static XmlError forCursor(String message, XmlCursor cursor) {
        return forCursor(message, SEVERITY_ERROR, cursor);
    }

    /**
     * Returns an XmlError for the given message, located at the XmlCursor, with {@link #SEVERITY_ERROR}.
     *
     * @param code   the error code
     * @param args   the arguments to use in formatting the error message
     * @param cursor the XmlCursor representing the location of the error
     */
    public static XmlError forCursor(String code, Object[] args, XmlCursor cursor) {
        return forCursor(code, args, SEVERITY_ERROR, cursor);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located at the XmlCursor.
     *
     * @param message  the error message
     * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param cursor   the XmlCursor representing the location of the error
     */
    public static XmlError forCursor(String message, int severity, XmlCursor cursor) {
        return new XmlError(message, (String) null, severity, cursor);
    }

    /**
     * Returns an XmlError for the given message, with the given severity, located at the XmlCursor.
     *
     * @param code     the error code
     * @param args     the arguments to use in formatting the error message
     * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
     * @param cursor   the XmlCursor representing the location of the error
     */
    public static XmlError forCursor(String code, Object[] args, int severity, XmlCursor cursor) {
        return new XmlError(code, args, severity, cursor);
    }

    /**
     * Tries to produce a nicely formatted filename from the given string.
     */
    protected static String formattedFileName(String rawString, URI base) {
        if (rawString == null) {
            return null;
        }

        URI uri;

        try {
            // if it looks like an absolute URI, treat it as such
            uri = new URI(rawString);

            // otherwise, treat it like a filename
            if (!uri.isAbsolute()) {
                uri = null;
            }
        } catch (URISyntaxException e) {
            uri = null;
        }

        // looks like a filename; convert it to uri for relativization
        if (uri == null) {
            uri = new File(rawString).toURI();
        }

        if (base != null) {
            uri = base.relativize(uri);
        }

        // filenames get their file: stripped off and their /'s turned into \'s (MSDOS)
        if (uri.isAbsolute() ? uri.getScheme().compareToIgnoreCase("file") == 0 :
            base != null && base.isAbsolute() && base.getScheme().compareToIgnoreCase("file") == 0) {
            try {
                return (new File(uri)).toString();
            } catch (Exception ignored) {
            }
        }

        return uri.toString();
    }

    /**
     * Tries to format a message using the error code.
     */
    public static String formattedMessage(String code, Object[] args) {
        if (code == null) {
            return null;
        }

        try {
            return new MessageFormat(_bundle.getString(code), Locale.ROOT).format(args);
        } catch (MissingResourceException | IllegalArgumentException e) {
            String bnd = (e instanceof MissingResourceException) ? "message.missing.resource" : "message.pattern.invalid";
            return new MessageFormat(_bundle.getString(bnd), Locale.ROOT).format(e.getMessage());
        }
    }

    /**
     * An error. See {@link #getSeverity}.
     */
    public static final int SEVERITY_ERROR = 0;
    /**
     * A warning. See {@link #getSeverity}.
     */
    public static final int SEVERITY_WARNING = 1;
    /**
     * An informational message. See {@link #getSeverity}.
     */
    public static final int SEVERITY_INFO = 2;

    /**
     * Returns the severity.  Either {@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}.
     */
    public int getSeverity() {
        return _severity;
    }

    /**
     * Returns the error message without location information.
     */
    public String getMessage() {
        return _message;
    }

    /**
     * Returns the error code or null. See {@link XmlErrorCodes}.
     */
    public String getErrorCode() {
        return _code;
    }

    /**
     * Returns the URL (or other name) of the file with the error, if available.
     */
    public String getSourceName() {
        return _source;
    }

    /**
     * Returns the line number of the error, if available, -1 if not.
     */
    public int getLine() {
        return _line;
    }

    /**
     * Returns the column number of the error, if available, -1 if not.
     */
    public int getColumn() {
        return _column;
    }

    /**
     * Returns the file character offset of the error, if available, -1 if not.
     */
    public int getOffset() {
        return _offset;
    }

    /**
     * Returns a location object of the given type.  XmlCursor.class and
     * XmlObject.class can be passed, for example.  Null if not available.
     */
    public Object getLocation(Object type) {
        if (type == XmlCursor.class) {
            return _cursor;
        }
        if (type == XmlObject.class && _cursor != null) {
            return _cursor.getObject();
        }
        return null;
    }

    /**
     * Returns a location of the error as an {@link XmlCursor}, null if
     * not available.
     */
    public XmlCursor getCursorLocation() {
        return (XmlCursor) getLocation(XmlCursor.class);
    }

    /**
     * Returns a location of the error as an {@link XmlObject}, null if
     * not available.
     */
    public XmlObject getObjectLocation() {
        return (XmlObject) getLocation(XmlObject.class);
    }

    /**
     * Produces a standard string for the error message, complete with
     * filename and location offsets if available.
     */
    public String toString() {
        return toString(null);
    }

    /**
     * Produces a standard string with the error message.  If a non-null
     * URI is supplied, source names are relativized against the given
     * URI.
     */
    public String toString(URI base) {
        // modified to carefully match the IDE's
        // workshop.workspace.ant.AntLogger regex
        // which also matches javac (davidbau)

        StringBuilder sb = new StringBuilder();

        String source = formattedFileName(getSourceName(), base);

        if (source != null) {
            sb.append(source);
            int line = getLine();
            if (line < 0) {
                line = 0;
            }

            sb.append(':');
            sb.append(line);
            sb.append(':');
            if (getColumn() > 0) {
                sb.append(getColumn());
                sb.append(':');
            }
            sb.append(" ");
        }

        switch (getSeverity()) {
            case SEVERITY_ERROR:
                sb.append("error: ");
                break;
            case SEVERITY_WARNING:
                sb.append("warning: ");
                break;
            case SEVERITY_INFO:
                break;
        }

        if (getErrorCode() != null) {
            sb.append(getErrorCode()).append(": ");
        }

        String msg = getMessage();

        sb.append(msg == null ? "<Unspecified message>" : msg);

        return sb.toString();
    }

    public static String severityAsString(int severity) {
        switch (severity) {
            case SEVERITY_ERROR:
                return ("error");
            case SEVERITY_WARNING:
                return ("warning");
            case SEVERITY_INFO:
                return "info";
            default:
                throw new IllegalArgumentException("unknown severity");
        }
    }
}
