# Copyright (c) 2009-2010 Arista Networks, Inc. - James Lingard
# Copyright (c) 2004-2010 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program 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 for more details
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


"""Checker for string formatting operations.
"""

import string
from logilab import astng
from pylint.interfaces import IASTNGChecker
from pylint.checkers import BaseChecker
from pylint.checkers import utils


MSGS = {
    'E1300': ("Unsupported format character %r (%#02x) at index %d",
              "Used when a unsupported format character is used in a format\
              string."),
    'E1301': ("Format string ends in middle of conversion specifier",
              "Used when a format string terminates before the end of a \
              conversion specifier."),
    'E1302': ("Mixing named and unnamed conversion specifiers in format string",
              "Used when a format string contains both named (e.g. '%(foo)d') \
              and unnamed (e.g. '%d') conversion specifiers.  This is also \
              used when a named conversion specifier contains * for the \
              minimum field width and/or precision."),
    'E1303': ("Expected mapping for format string, not %s",
              "Used when a format string that uses named conversion specifiers \
              is used with an argument that is not a mapping."),
    'W1300': ("Format string dictionary key should be a string, not %s",
              "Used when a format string that uses named conversion specifiers \
              is used with a dictionary whose keys are not all strings."),
    'W1301': ("Unused key %r in format string dictionary",
              "Used when a format string that uses named conversion specifiers \
              is used with a dictionary that conWtains keys not required by the \
              format string."),
    'E1304': ("Missing key %r in format string dictionary",
              "Used when a format string that uses named conversion specifiers \
              is used with a dictionary that doesn't contain all the keys \
              required by the format string."),
    'E1305': ("Too many arguments for format string",
              "Used when a format string that uses unnamed conversion \
              specifiers is given too few arguments."),
    'E1306': ("Not enough arguments for format string",
              "Used when a format string that uses unnamed conversion \
              specifiers is given too many arguments"),
    }

OTHER_NODES = (astng.Const, astng.List, astng.Backquote,
               astng.Lambda, astng.Function,
               astng.ListComp, astng.SetComp, astng.GenExpr)

class StringFormatChecker(BaseChecker):
    """Checks string formatting operations to ensure that the format string
    is valid and the arguments match the format string.
    """

    __implements__ = (IASTNGChecker,)
    name = 'string_format'
    msgs = MSGS

    def visit_binop(self, node):
        if node.op != '%':
            return
        left = node.left
        args = node.right

        if not (isinstance(left, astng.Const)
            and isinstance(left.value, basestring)):
            return
        format_string = left.value
        try:
            required_keys, required_num_args = \
                utils.parse_format_string(format_string)
        except utils.UnsupportedFormatCharacter, e:
            c = format_string[e.index]
            self.add_message('E1300', node=node, args=(c, ord(c), e.index))
            return
        except utils.IncompleteFormatString:
            self.add_message('E1301', node=node)
            return
        if required_keys and required_num_args:
            # The format string uses both named and unnamed format
            # specifiers.
            self.add_message('E1302', node=node)
        elif required_keys:
            # The format string uses only named format specifiers.
            # Check that the RHS of the % operator is a mapping object
            # that contains precisely the set of keys required by the
            # format string.
            if isinstance(args, astng.Dict):
                keys = set()
                unknown_keys = False
                for k, v in args.items:
                    if isinstance(k, astng.Const):
                        key = k.value
                        if isinstance(key, basestring):
                            keys.add(key)
                        else:
                            self.add_message('W1300', node=node, args=key)
                    else:
                        # One of the keys was something other than a
                        # constant.  Since we can't tell what it is,
                        # supress checks for missing keys in the
                        # dictionary.
                        unknown_keys = True
                if not unknown_keys:
                    for key in required_keys:
                        if key not in keys:
                            self.add_message('E1304', node=node, args=key)
                for key in keys:
                    if key not in required_keys:
                        self.add_message('W1301', node=node, args=key)
            elif isinstance(args, OTHER_NODES + (astng.Tuple,)):
                type_name = type(args).__name__
                self.add_message('E1303', node=node, args=type_name)
            # else:
                # The RHS of the format specifier is a name or
                # expression.  It may be a mapping object, so
                # there's nothing we can check.
        else:
            # The format string uses only unnamed format specifiers.
            # Check that the number of arguments passed to the RHS of
            # the % operator matches the number required by the format
            # string.
            if isinstance(args, astng.Tuple):
                num_args = len(args.elts)
            elif isinstance(args, OTHER_NODES + (astng.Dict, astng.DictComp)):
                num_args = 1
            else:
                # The RHS of the format specifier is a name or
                # expression.  It could be a tuple of unknown size, so
                # there's nothing we can check.
                num_args = None
            if num_args is not None:
                if num_args > required_num_args:
                    self.add_message('E1305', node=node)
                elif num_args < required_num_args:
                    self.add_message('E1306', node=node)


def register(linter):
    """required method to auto register this checker """
    linter.register_checker(StringFormatChecker(linter))
