#     Copyright 2013, Kay Hayen, mailto:kay.hayen@gmail.com
#
#     Part of "Nuitka", an optimizing Python compiler that is compatible and
#     integrates with CPython, but also works on its own.
#
#     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.
#
""" Handling of syntax errors.

Format SyntaxError/IndentationError exception for output, as well as
raise it for the given source code reference.
"""

def formatOutput(e):
    if len( e.args ) > 1:
        reason, ( filename, lineno, colno, message ) = e.args

        if message is None and colno is not None:
            colno = None
    else:
        reason, = e.args

        filename = None
        lineno = None
        colno = None
        message = None

    if colno is not None:
        colno = colno - len( message ) + len( message.lstrip() )

        return """\
  File "%s", line %d
    %s
    %s^
%s: %s""" % (
            filename,
            lineno,
            message.strip(),
            " " * (colno-1) if colno is not None else "",
            e.__class__.__name__,
            reason
         )
    elif message is not None:
        return """\
  File "%s", line %d
    %s
%s: %s""" % (
            filename,
            lineno,
            message.strip(),
            e.__class__.__name__,
            reason
         )
    elif filename is not None:
        return """\
  File "%s", line %s
%s: %s""" % (
            filename,
            lineno,
            e.__class__.__name__,
            reason
         )
    else:
        return """\
%s: %s""" % (
            e.__class__.__name__,
            reason
         )


def raiseSyntaxError(reason, source_ref, col_offset = None, display_file = True,
                     display_line = True, source_line = None):

    # TODO: This could could "linecache" module maybe.
    def readSource():
        source = open(source_ref.getFilename(), 'rU').readlines()

        return source[source_ref.getLineNumber() - 1]

    if display_file and display_line:
        if source_line is None:
            source_line = readSource()

        raise SyntaxError(
            reason,
            (
                source_ref.getFilename(),
                source_ref.getLineNumber(),
                col_offset,
                source_line
            )
        )
    else:
        if source_ref is not None:
            if source_line is None and display_line:
                source_line = readSource()

            raise SyntaxError(
                reason,
                (
                    source_ref.getFilename(),
                    source_ref.getLineNumber(),
                    None,
                    source_line
                )
            )
        else:
            raise SyntaxError(
                reason,
                (
                    None,
                    None,
                    None,
                    None
                )
            )
