# Copyright (c) 2011 The Chromium OS Authors.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# 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
#

import command
import gitutil
import os
import re
import sys
import terminal

def FindCheckPatch():
    top_level = gitutil.GetTopLevel()
    try_list = [
        os.getcwd(),
        os.path.join(os.getcwd(), '..', '..'),
        os.path.join(top_level, 'tools'),
        os.path.join(top_level, 'scripts'),
        '%s/bin' % os.getenv('HOME'),
        ]
    # Look in current dir
    for path in try_list:
        fname = os.path.join(path, 'checkpatch.pl')
        if os.path.isfile(fname):
            return fname

    # Look upwwards for a Chrome OS tree
    while not os.path.ismount(path):
        fname = os.path.join(path, 'src', 'third_party', 'kernel', 'files',
                'scripts', 'checkpatch.pl')
        if os.path.isfile(fname):
            return fname
        path = os.path.dirname(path)

    print >> sys.stderr, ('Cannot find checkpatch.pl - please put it in your ' +
                '~/bin directory or use --no-check')
    sys.exit(1)

def CheckPatch(fname, verbose=False):
    """Run checkpatch.pl on a file.

    Returns:
        4-tuple containing:
            result: False=failure, True=ok
            problems: List of problems, each a dict:
                'type'; error or warning
                'msg': text message
                'file' : filename
                'line': line number
            lines: Number of lines
    """
    result = False
    error_count, warning_count, lines = 0, 0, 0
    problems = []
    chk = FindCheckPatch()
    item = {}
    stdout = command.Output(chk, '--no-tree', fname)
    #pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    #stdout, stderr = pipe.communicate()

    # total: 0 errors, 0 warnings, 159 lines checked
    re_stats = re.compile('total: (\\d+) errors, (\d+) warnings, (\d+)')
    re_ok = re.compile('.*has no obvious style problems')
    re_bad = re.compile('.*has style problems, please review')
    re_error = re.compile('ERROR: (.*)')
    re_warning = re.compile('WARNING: (.*)')
    re_file = re.compile('#\d+: FILE: ([^:]*):(\d+):')

    for line in stdout.splitlines():
        if verbose:
            print line

        # A blank line indicates the end of a message
        if not line and item:
            problems.append(item)
            item = {}
        match = re_stats.match(line)
        if match:
            error_count = int(match.group(1))
            warning_count = int(match.group(2))
            lines = int(match.group(3))
        elif re_ok.match(line):
            result = True
        elif re_bad.match(line):
            result = False
        match = re_error.match(line)
        if match:
            item['msg'] = match.group(1)
            item['type'] = 'error'
        match = re_warning.match(line)
        if match:
            item['msg'] = match.group(1)
            item['type'] = 'warning'
        match = re_file.match(line)
        if match:
            item['file'] = match.group(1)
            item['line'] = int(match.group(2))

    return result, problems, error_count, warning_count, lines, stdout

def GetWarningMsg(col, msg_type, fname, line, msg):
    '''Create a message for a given file/line

    Args:
        msg_type: Message type ('error' or 'warning')
        fname: Filename which reports the problem
        line: Line number where it was noticed
        msg: Message to report
    '''
    if msg_type == 'warning':
        msg_type = col.Color(col.YELLOW, msg_type)
    elif msg_type == 'error':
        msg_type = col.Color(col.RED, msg_type)
    return '%s: %s,%d: %s' % (msg_type, fname, line, msg)

def CheckPatches(verbose, args):
    '''Run the checkpatch.pl script on each patch'''
    error_count = 0
    warning_count = 0
    col = terminal.Color()

    for fname in args:
        ok, problems, errors, warnings, lines, stdout = CheckPatch(fname,
                verbose)
        if not ok:
            error_count += errors
            warning_count += warnings
            print '%d errors, %d warnings for %s:' % (errors,
                    warnings, fname)
            if len(problems) != error_count + warning_count:
                print "Internal error: some problems lost"
            for item in problems:
                print GetWarningMsg(col, item['type'],
                        item.get('file', '<unknown>'),
                        item.get('line', 0), item['msg'])
            #print stdout
    if error_count != 0 or warning_count != 0:
        str = 'checkpatch.pl found %d error(s), %d warning(s)' % (
            error_count, warning_count)
        color = col.GREEN
        if warning_count:
            color = col.YELLOW
        if error_count:
            color = col.RED
        print col.Color(color, str)
        return False
    return True
