# 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 os
import re
import shutil
import tempfile

import command
import commit
import gitutil
from series import Series

# Tags that we detect and remove
re_remove = re.compile('^BUG=|^TEST=|^BRANCH=|^Change-Id:|^Review URL:'
    '|Reviewed-on:|Reviewed-by:|Commit-Ready:')

# Lines which are allowed after a TEST= line
re_allowed_after_test = re.compile('^Signed-off-by:')

# Signoffs
re_signoff = re.compile('^Signed-off-by:')

# The start of the cover letter
re_cover = re.compile('^Cover-letter:')

# Patch series tag
re_series = re.compile('^Series-(\w*): *(.*)')

# Commit tags that we want to collect and keep
re_tag = re.compile('^(Tested-by|Acked-by|Cc): (.*)')

# The start of a new commit in the git log
re_commit = re.compile('^commit (.*)')

# We detect these since checkpatch doesn't always do it
re_space_before_tab = re.compile('^[+].* \t')

# States we can be in - can we use range() and still have comments?
STATE_MSG_HEADER = 0        # Still in the message header
STATE_PATCH_SUBJECT = 1     # In patch subject (first line of log for a commit)
STATE_PATCH_HEADER = 2      # In patch header (after the subject)
STATE_DIFFS = 3             # In the diff part (past --- line)

class PatchStream:
    """Class for detecting/injecting tags in a patch or series of patches

    We support processing the output of 'git log' to read out the tags we
    are interested in. We can also process a patch file in order to remove
    unwanted tags or inject additional ones. These correspond to the two
    phases of processing.
    """
    def __init__(self, series, name=None, is_log=False):
        self.skip_blank = False          # True to skip a single blank line
        self.found_test = False          # Found a TEST= line
        self.lines_after_test = 0        # MNumber of lines found after TEST=
        self.warn = []                   # List of warnings we have collected
        self.linenum = 1                 # Output line number we are up to
        self.in_section = None           # Name of start...END section we are in
        self.notes = []                  # Series notes
        self.section = []                # The current section...END section
        self.series = series             # Info about the patch series
        self.is_log = is_log             # True if indent like git log
        self.in_change = 0               # Non-zero if we are in a change list
        self.blank_count = 0             # Number of blank lines stored up
        self.state = STATE_MSG_HEADER    # What state are we in?
        self.tags = []                   # Tags collected, like Tested-by...
        self.signoff = []                # Contents of signoff line
        self.commit = None               # Current commit

    def AddToSeries(self, line, name, value):
        """Add a new Series-xxx tag.

        When a Series-xxx tag is detected, we come here to record it, if we
        are scanning a 'git log'.

        Args:
            line: Source line containing tag (useful for debug/error messages)
            name: Tag name (part after 'Series-')
            value: Tag value (part after 'Series-xxx: ')
        """
        if name == 'notes':
            self.in_section = name
            self.skip_blank = False
        if self.is_log:
            self.series.AddTag(self.commit, line, name, value)

    def CloseCommit(self):
        """Save the current commit into our commit list, and reset our state"""
        if self.commit and self.is_log:
            self.series.AddCommit(self.commit)
            self.commit = None

    def FormatTags(self, tags):
        out_list = []
        for tag in sorted(tags):
            if tag.startswith('Cc:'):
                tag_list = tag[4:].split(',')
                out_list += gitutil.BuildEmailList(tag_list, 'Cc:')
            else:
                out_list.append(tag)
        return out_list

    def ProcessLine(self, line):
        """Process a single line of a patch file or commit log

        This process a line and returns a list of lines to output. The list
        may be empty or may contain multiple output lines.

        This is where all the complicated logic is located. The class's
        state is used to move between different states and detect things
        properly.

        We can be in one of two modes:
            self.is_log == True: This is 'git log' mode, where most output is
                indented by 4 characters and we are scanning for tags

            self.is_log == False: This is 'patch' mode, where we already have
                all the tags, and are processing patches to remove junk we
                don't want, and add things we think are required.

        Args:
            line: text line to process

        Returns:
            list of output lines, or [] if nothing should be output
        """
        # Initially we have no output. Prepare the input line string
        out = []
        line = line.rstrip('\n')
        if self.is_log:
            if line[:4] == '    ':
                line = line[4:]

        # Handle state transition and skipping blank lines
        series_match = re_series.match(line)
        commit_match = re_commit.match(line) if self.is_log else None
        tag_match = None
        if self.state == STATE_PATCH_HEADER:
            tag_match = re_tag.match(line)
        is_blank = not line.strip()
        if is_blank:
            if (self.state == STATE_MSG_HEADER
                    or self.state == STATE_PATCH_SUBJECT):
                self.state += 1

            # We don't have a subject in the text stream of patch files
            # It has its own line with a Subject: tag
            if not self.is_log and self.state == STATE_PATCH_SUBJECT:
                self.state += 1
        elif commit_match:
            self.state = STATE_MSG_HEADER

        # If we are in a section, keep collecting lines until we see END
        if self.in_section:
            if line == 'END':
                if self.in_section == 'cover':
                    self.series.cover = self.section
                elif self.in_section == 'notes':
                    if self.is_log:
                        self.series.notes += self.section
                else:
                    self.warn.append("Unknown section '%s'" % self.in_section)
                self.in_section = None
                self.skip_blank = True
                self.section = []
            else:
                self.section.append(line)

        # Detect the commit subject
        elif not is_blank and self.state == STATE_PATCH_SUBJECT:
            self.commit.subject = line

        # Detect the tags we want to remove, and skip blank lines
        elif re_remove.match(line):
            self.skip_blank = True

            # TEST= should be the last thing in the commit, so remove
            # everything after it
            if line.startswith('TEST='):
                self.found_test = True
        elif self.skip_blank and is_blank:
            self.skip_blank = False

        # Detect the start of a cover letter section
        elif re_cover.match(line):
            self.in_section = 'cover'
            self.skip_blank = False

        # If we are in a change list, key collected lines until a blank one
        elif self.in_change:
            if is_blank:
                # Blank line ends this change list
                self.in_change = 0
            elif line == '---' or re_signoff.match(line):
                self.in_change = 0
                out = self.ProcessLine(line)
            else:
                if self.is_log:
                    self.series.AddChange(self.in_change, self.commit, line)
            self.skip_blank = False

        # Detect Series-xxx tags
        elif series_match:
            name = series_match.group(1)
            value = series_match.group(2)
            if name == 'changes':
                # value is the version number: e.g. 1, or 2
                try:
                    value = int(value)
                except ValueError as str:
                    raise ValueError("%s: Cannot decode version info '%s'" %
                        (self.commit.hash, line))
                self.in_change = int(value)
            else:
                self.AddToSeries(line, name, value)
                self.skip_blank = True

        # Detect the start of a new commit
        elif commit_match:
            self.CloseCommit()
            self.commit = commit.Commit(commit_match.group(1)[:7])

        # Detect tags in the commit message
        elif tag_match:
            # Remove Tested-by self, since few will take much notice
            if (tag_match.group(1) == 'Tested-by' and
                    tag_match.group(2).find(os.getenv('USER') + '@') != -1):
                self.warn.append("Ignoring %s" % line)
            elif tag_match.group(1) == 'Cc':
                self.commit.AddCc(tag_match.group(2).split(','))
            else:
                self.tags.append(line);

        # Well that means this is an ordinary line
        else:
            pos = 1
            # Look for ugly ASCII characters
            for ch in line:
                # TODO: Would be nicer to report source filename and line
                if ord(ch) > 0x80:
                    self.warn.append("Line %d/%d ('%s') has funny ascii char" %
                        (self.linenum, pos, line))
                pos += 1

            # Look for space before tab
            m = re_space_before_tab.match(line)
            if m:
                self.warn.append('Line %d/%d has space before tab' %
                    (self.linenum, m.start()))

            # OK, we have a valid non-blank line
            out = [line]
            self.linenum += 1
            self.skip_blank = False
            if self.state == STATE_DIFFS:
                pass

            # If this is the start of the diffs section, emit our tags and
            # change log
            elif line == '---':
                self.state = STATE_DIFFS

                # Output the tags (signeoff first), then change list
                out = []
                log = self.series.MakeChangeLog(self.commit)
                out += self.FormatTags(self.tags)
                out += [line] + log
            elif self.found_test:
                if not re_allowed_after_test.match(line):
                    self.lines_after_test += 1

        return out

    def Finalize(self):
        """Close out processing of this patch stream"""
        self.CloseCommit()
        if self.lines_after_test:
            self.warn.append('Found %d lines after TEST=' %
                    self.lines_after_test)

    def ProcessStream(self, infd, outfd):
        """Copy a stream from infd to outfd, filtering out unwanting things.

        This is used to process patch files one at a time.

        Args:
            infd: Input stream file object
            outfd: Output stream file object
        """
        # Extract the filename from each diff, for nice warnings
        fname = None
        last_fname = None
        re_fname = re.compile('diff --git a/(.*) b/.*')
        while True:
            line = infd.readline()
            if not line:
                break
            out = self.ProcessLine(line)

            # Try to detect blank lines at EOF
            for line in out:
                match = re_fname.match(line)
                if match:
                    last_fname = fname
                    fname = match.group(1)
                if line == '+':
                    self.blank_count += 1
                else:
                    if self.blank_count and (line == '-- ' or match):
                        self.warn.append("Found possible blank line(s) at "
                                "end of file '%s'" % last_fname)
                    outfd.write('+\n' * self.blank_count)
                    outfd.write(line + '\n')
                    self.blank_count = 0
        self.Finalize()


def GetMetaData(start, count):
    """Reads out patch series metadata from the commits

    This does a 'git log' on the relevant commits and pulls out the tags we
    are interested in.

    Args:
        start: Commit to start from: 0=HEAD, 1=next one, etc.
        count: Number of commits to list
    """
    pipe = [['git', 'log', '--no-color', '--reverse', 'HEAD~%d' % start,
	'-n%d' % count]]
    stdout = command.RunPipe(pipe, capture=True)
    series = Series()
    ps = PatchStream(series, is_log=True)
    for line in stdout.splitlines():
        ps.ProcessLine(line)
    ps.Finalize()
    return series

def FixPatch(backup_dir, fname, series, commit):
    """Fix up a patch file, by adding/removing as required.

    We remove our tags from the patch file, insert changes lists, etc.
    The patch file is processed in place, and overwritten.

    A backup file is put into backup_dir (if not None).

    Args:
        fname: Filename to patch file to process
        series: Series information about this patch set
        commit: Commit object for this patch file
    Return:
        A list of errors, or [] if all ok.
    """
    handle, tmpname = tempfile.mkstemp()
    outfd = os.fdopen(handle, 'w')
    infd = open(fname, 'r')
    ps = PatchStream(series)
    ps.commit = commit
    ps.ProcessStream(infd, outfd)
    infd.close()
    outfd.close()

    # Create a backup file if required
    if backup_dir:
        shutil.copy(fname, os.path.join(backup_dir, os.path.basename(fname)))
    shutil.move(tmpname, fname)
    return ps.warn

def FixPatches(series, fnames):
    """Fix up a list of patches identified by filenames

    The patch files are processed in place, and overwritten.

    Args:
        series: The series object
        fnames: List of patch files to process
    """
    # Current workflow creates patches, so we shouldn't need a backup
    backup_dir = None  #tempfile.mkdtemp('clean-patch')
    count = 0
    for fname in fnames:
        commit = series.commits[count]
        commit.patch = fname
        result = FixPatch(backup_dir, fname, series, commit)
        if result:
            print '%d warnings for %s:' % (len(result), fname)
            for warn in result:
                print '\t', warn
            print
        count += 1
    print 'Cleaned %d patches' % count
    return series

def InsertCoverLetter(fname, series, count):
    """Inserts a cover letter with the required info into patch 0

    Args:
        fname: Input / output filename of the cover letter file
        series: Series object
        count: Number of patches in the series
    """
    fd = open(fname, 'r')
    lines = fd.readlines()
    fd.close()

    fd = open(fname, 'w')
    text = series.cover
    prefix = series.GetPatchPrefix()
    for line in lines:
        if line.startswith('Subject:'):
            # TODO: if more than 10 patches this should save 00/xx, not 0/xx
            line = 'Subject: [%s 0/%d] %s\n' % (prefix, count, text[0])

        # Insert our cover letter
        elif line.startswith('*** BLURB HERE ***'):
            # First the blurb test
            line = '\n'.join(text[1:]) + '\n'
            if series.get('notes'):
                line += '\n'.join(series.notes) + '\n'

            # Now the change list
            out = series.MakeChangeLog(None)
            line += '\n' + '\n'.join(out)
        fd.write(line)
    fd.close()
