# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2011 The Chromium OS Authors.
#

"""Handles parsing a stream of commits/emails from 'git log' or other source"""

import collections
import datetime
import io
import math
import os
import re
import queue
import shutil
import tempfile

from patman import commit
from patman.series import Series
from u_boot_pylib import command
from u_boot_pylib import gitutil

# Tags that we detect and remove
RE_REMOVE = re.compile(r'^BUG=|^TEST=|^BRANCH=|^Review URL:'
                       r'|Reviewed-on:|Commit-\w*:')

# 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: *(.*)')

# Cover letter tag
RE_COVER = re.compile('^Cover-([a-z-]*): *(.*)')

# Patch series tag
RE_SERIES_TAG = re.compile('^Series-([a-z-]*): *(.*)')

# Change-Id will be used to generate the Message-Id and then be stripped
RE_CHANGE_ID = re.compile('^Change-Id: *(.*)')

# Commit series tag
RE_COMMIT_TAG = re.compile('^Commit-([a-z-]*): *(.*)')

# Commit tags that we want to collect and keep
RE_TAG = re.compile('^(Tested-by|Acked-by|Reviewed-by|Patch-cc|Fixes): (.*)')

# The start of a new commit in the git log
RE_COMMIT = re.compile('^commit ([0-9a-f]*)$')

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

# Match indented lines for changes
RE_LEADING_WHITESPACE = re.compile(r'^\s')

# Detect a 'diff' line
RE_DIFF = re.compile(r'^>.*diff --git a/(.*) b/(.*)$')

# Detect a context line, like '> @@ -153,8 +153,13 @@ CheckPatch
RE_LINE = re.compile(r'>.*@@ \-(\d+),\d+ \+(\d+),\d+ @@ *(.*)')

# Detect line with invalid TAG
RE_INV_TAG = re.compile('^Serie-([a-z-]*): *(.*)')

# 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.

    Args:
        keep_change_id (bool): Keep the Change-Id tag
        insert_base_commit (bool): True to add the base commit to the end
    """
    def __init__(self, series, is_log=False, keep_change_id=False,
                 insert_base_commit=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        # Number of lines found after TEST=
        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.keep_change_id = keep_change_id  # True to keep Change-Id tags
        self.in_change = None            # Name of the change list we are in
        self.change_version = 0          # Non-zero if we are in a change list
        self.change_lines = []           # Lines of the current change
        self.blank_count = 0             # Number of blank lines stored up
        self.state = STATE_MSG_HEADER    # What state are we in?
        self.commit = None               # Current commit
        # List of unquoted test blocks, each a list of str lines
        self.snippets = []
        self.cur_diff = None             # Last 'diff' line seen (str)
        self.cur_line = None             # Last context (@@) line seen (str)
        self.recent_diff = None          # 'diff' line for current snippet (str)
        self.recent_line = None          # '@@' line for current snippet (str)
        self.recent_quoted = collections.deque([], 5)
        self.recent_unquoted = queue.Queue()
        self.was_quoted = None
        self.insert_base_commit = insert_base_commit

    @staticmethod
    def process_text(text, is_comment=False):
        """Process some text through this class using a default Commit/Series

        Args:
            text (str): Text to parse
            is_comment (bool): True if this is a comment rather than a patch.
                If True, PatchStream doesn't expect a patch subject at the
                start, but jumps straight into the body

        Returns:
            PatchStream: object with results
        """
        pstrm = PatchStream(Series())
        pstrm.commit = commit.Commit(None)
        infd = io.StringIO(text)
        outfd = io.StringIO()
        if is_comment:
            pstrm.state = STATE_PATCH_HEADER
        pstrm.process_stream(infd, outfd)
        return pstrm

    def _add_warn(self, warn):
        """Add a new warning to report to the user about the current commit

        The new warning is added to the current commit if not already present.

        Args:
            warn (str): Warning to report

        Raises:
            ValueError: Warning is generated with no commit associated
        """
        if not self.commit:
            print('Warning outside commit: %s' % warn)
        elif warn not in self.commit.warn:
            self.commit.warn.append(warn)

    def _add_to_series(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 (str): Source line containing tag (useful for debug/error
                messages)
            name (str): Tag name (part after 'Series-')
            value (str): Tag value (part after 'Series-xxx: ')
        """
        if name == 'notes':
            self.in_section = name
            self.skip_blank = False
        if self.is_log:
            warn = self.series.AddTag(self.commit, line, name, value)
            if warn:
                self.commit.warn.append(warn)

    def _add_to_commit(self, name):
        """Add a new Commit-xxx tag.

        When a Commit-xxx tag is detected, we come here to record it.

        Args:
            name (str): Tag name (part after 'Commit-')
        """
        if name == 'notes':
            self.in_section = 'commit-' + name
            self.skip_blank = False

    def _add_commit_rtag(self, rtag_type, who):
        """Add a response tag to the current commit

        Args:
            rtag_type (str): rtag type (e.g. 'Reviewed-by')
            who (str): Person who gave that rtag, e.g.
                 'Fred Bloggs <fred@bloggs.org>'
        """
        self.commit.add_rtag(rtag_type, who)

    def _close_commit(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
        # If 'END' is missing in a 'Cover-letter' section, and that section
        # happens to show up at the very end of the commit message, this is
        # the chance for us to fix it up.
        if self.in_section == 'cover' and self.is_log:
            self.series.cover = self.section
            self.in_section = None
            self.skip_blank = True
            self.section = []

        self.cur_diff = None
        self.recent_diff = None
        self.recent_line = None

    def _parse_version(self, value, line):
        """Parse a version from a *-changes tag

        Args:
            value (str): Tag value (part after 'xxx-changes: '
            line (str): Source line containing tag

        Returns:
            int: The version as an integer

        Raises:
            ValueError: the value cannot be converted
        """
        try:
            return int(value)
        except ValueError:
            raise ValueError("%s: Cannot decode version info '%s'" %
                             (self.commit.hash, line))

    def _finalise_change(self):
        """_finalise a (multi-line) change and add it to the series or commit"""
        if not self.change_lines:
            return
        change = '\n'.join(self.change_lines)

        if self.in_change == 'Series':
            self.series.AddChange(self.change_version, self.commit, change)
        elif self.in_change == 'Cover':
            self.series.AddChange(self.change_version, None, change)
        elif self.in_change == 'Commit':
            self.commit.add_change(self.change_version, change)
        self.change_lines = []

    def _finalise_snippet(self):
        """Finish off a snippet and add it to the list

        This is called when we get to the end of a snippet, i.e. the we enter
        the next block of quoted text:

            This is a comment from someone.

            Something else

            > Now we have some code          <----- end of snippet
            > more code

            Now a comment about the above code

        This adds the snippet to our list
        """
        quoted_lines = []
        while self.recent_quoted:
            quoted_lines.append(self.recent_quoted.popleft())
        unquoted_lines = []
        valid = False
        while not self.recent_unquoted.empty():
            text = self.recent_unquoted.get()
            if not (text.startswith('On ') and text.endswith('wrote:')):
                unquoted_lines.append(text)
            if text:
                valid = True
        if valid:
            lines = []
            if self.recent_diff:
                lines.append('> File: %s' % self.recent_diff)
            if self.recent_line:
                out = '> Line: %s / %s' % self.recent_line[:2]
                if self.recent_line[2]:
                    out += ': %s' % self.recent_line[2]
                lines.append(out)
            lines += quoted_lines + unquoted_lines
            if lines:
                self.snippets.append(lines)

    def process_line(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 (str): text line to process

        Returns:
            list: list of output lines, or [] if nothing should be output

        Raises:
            ValueError: a fatal error occurred while parsing, e.g. an END
                without a starting tag, or two commits with two change IDs
        """
        # Initially we have no output. Prepare the input line string
        out = []
        line = line.rstrip('\n')

        commit_match = RE_COMMIT.match(line) if self.is_log else None

        if self.is_log:
            if line[:4] == '    ':
                line = line[4:]

        # Handle state transition and skipping blank lines
        series_tag_match = RE_SERIES_TAG.match(line)
        change_id_match = RE_CHANGE_ID.match(line)
        commit_tag_match = RE_COMMIT_TAG.match(line)
        cover_match = RE_COVER.match(line)
        signoff_match = RE_SIGNOFF.match(line)
        leading_whitespace_match = RE_LEADING_WHITESPACE.match(line)
        diff_match = RE_DIFF.match(line)
        line_match = RE_LINE.match(line)
        invalid_match = RE_INV_TAG.match(line)
        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 a tag is detected, or a new commit starts
        if series_tag_match or commit_tag_match or change_id_match or \
           cover_match or signoff_match or self.state == STATE_MSG_HEADER:
            # but we are already in a section, this means 'END' is missing
            # for that section, fix it up.
            if self.in_section:
                self._add_warn("Missing 'END' in section '%s'" % self.in_section)
                if self.in_section == 'cover':
                    self.series.cover = self.section
                elif self.in_section == 'notes':
                    if self.is_log:
                        self.series.notes += self.section
                elif self.in_section == 'commit-notes':
                    if self.is_log:
                        self.commit.notes += self.section
                else:
                    # This should not happen
                    raise ValueError("Unknown section '%s'" % self.in_section)
                self.in_section = None
                self.skip_blank = True
                self.section = []
            # but we are already in a change list, that means a blank line
            # is missing, fix it up.
            if self.in_change:
                self._add_warn("Missing 'blank line' in section '%s-changes'" %
                               self.in_change)
                self._finalise_change()
                self.in_change = None
                self.change_version = 0

        # 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
                elif self.in_section == 'commit-notes':
                    if self.is_log:
                        self.commit.notes += self.section
                else:
                    # This should not happen
                    raise ValueError("Unknown section '%s'" % self.in_section)
                self.in_section = None
                self.skip_blank = True
                self.section = []
            else:
                self.section.append(line)

        # If we are not in a section, it is an unexpected END
        elif line == 'END':
            raise ValueError("'END' wihout section")

        # 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) and not commit_tag_match:
            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 Cover-xxx tags
        elif cover_match:
            name = cover_match.group(1)
            value = cover_match.group(2)
            if name == 'letter':
                self.in_section = 'cover'
                self.skip_blank = False
            elif name == 'letter-cc':
                self._add_to_series(line, 'cover-cc', value)
            elif name == 'changes':
                self.in_change = 'Cover'
                self.change_version = self._parse_version(value, line)

        # 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._finalise_change()
                self.in_change = None
                self.change_version = 0
            elif line == '---':
                self._finalise_change()
                self.in_change = None
                self.change_version = 0
                out = self.process_line(line)
            elif self.is_log:
                if not leading_whitespace_match:
                    self._finalise_change()
                self.change_lines.append(line)
            self.skip_blank = False

        # Detect Series-xxx tags
        elif series_tag_match:
            name = series_tag_match.group(1)
            value = series_tag_match.group(2)
            if name == 'changes':
                # value is the version number: e.g. 1, or 2
                self.in_change = 'Series'
                self.change_version = self._parse_version(value, line)
            else:
                self._add_to_series(line, name, value)
                self.skip_blank = True

        # Detect Change-Id tags
        elif change_id_match:
            if self.keep_change_id:
                out = [line]
            value = change_id_match.group(1)
            if self.is_log:
                if self.commit.change_id:
                    raise ValueError(
                        "%s: Two Change-Ids: '%s' vs. '%s'" %
                        (self.commit.hash, self.commit.change_id, value))
                self.commit.change_id = value
            self.skip_blank = True

        # Detect Commit-xxx tags
        elif commit_tag_match:
            name = commit_tag_match.group(1)
            value = commit_tag_match.group(2)
            if name == 'notes':
                self._add_to_commit(name)
                self.skip_blank = True
            elif name == 'changes':
                self.in_change = 'Commit'
                self.change_version = self._parse_version(value, line)
            elif name == 'cc':
                self.commit.add_cc(value.split(','))
            elif name == 'added-in':
                version = self._parse_version(value, line)
                self.commit.add_change(version, '- New')
                self.series.AddChange(version, None, '- %s' %
                                      self.commit.subject)
            else:
                self._add_warn('Line %d: Ignoring Commit-%s' %
                               (self.linenum, name))

        # Detect invalid tags
        elif invalid_match:
            raise ValueError("Line %d: Invalid tag = '%s'" %
                (self.linenum, line))

        # Detect the start of a new commit
        elif commit_match:
            self._close_commit()
            self.commit = commit.Commit(commit_match.group(1))

        # Detect tags in the commit message
        elif tag_match:
            rtag_type, who = tag_match.groups()
            self._add_commit_rtag(rtag_type, who)
            # Remove Tested-by self, since few will take much notice
            if (rtag_type == 'Tested-by' and
                    who.find(os.getenv('USER') + '@') != -1):
                self._add_warn("Ignoring '%s'" % line)
            elif rtag_type == 'Patch-cc':
                self.commit.add_cc(who.split(','))
            else:
                out = [line]

        # Suppress duplicate signoffs
        elif signoff_match:
            if (self.is_log or not self.commit or
                    self.commit.check_duplicate_signoff(signoff_match.group(1))):
                out = [line]

        # Well that means this is an ordinary line
        else:
            # Look for space before tab
            mat = RE_SPACE_BEFORE_TAB.match(line)
            if mat:
                self._add_warn('Line %d/%d has space before tab' %
                               (self.linenum, mat.start()))

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

            if diff_match:
                self.cur_diff = diff_match.group(1)

            # If this is quoted, keep recent lines
            if not diff_match and self.linenum > 1 and line:
                if line.startswith('>'):
                    if not self.was_quoted:
                        self._finalise_snippet()
                        self.recent_line = None
                    if not line_match:
                        self.recent_quoted.append(line)
                    self.was_quoted = True
                    self.recent_diff = self.cur_diff
                else:
                    self.recent_unquoted.put(line)
                    self.was_quoted = False

            if line_match:
                self.recent_line = line_match.groups()

            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 (signoff first), then change list
                out = []
                log = self.series.MakeChangeLog(self.commit)
                out += [line]
                if self.commit:
                    out += self.commit.notes
                out += [''] + log
            elif self.found_test:
                if not RE_ALLOWED_AFTER_TEST.match(line):
                    self.lines_after_test += 1

        return out

    def finalise(self):
        """Close out processing of this patch stream"""
        self._finalise_snippet()
        self._finalise_change()
        self._close_commit()
        if self.lines_after_test:
            self._add_warn('Found %d lines after TEST=' % self.lines_after_test)

    def _write_message_id(self, outfd):
        """Write the Message-Id into the output.

        This is based on the Change-Id in the original patch, the version,
        and the prefix.

        Args:
            outfd (io.IOBase): Output stream file object
        """
        if not self.commit.change_id:
            return

        # If the count is -1 we're testing, so use a fixed time
        if self.commit.count == -1:
            time_now = datetime.datetime(1999, 12, 31, 23, 59, 59)
        else:
            time_now = datetime.datetime.now()

        # In theory there is email.utils.make_msgid() which would be nice
        # to use, but it already produces something way too long and thus
        # will produce ugly commit lines if someone throws this into
        # a "Link:" tag in the final commit.  So (sigh) roll our own.

        # Start with the time; presumably we wouldn't send the same series
        # with the same Change-Id at the exact same second.
        parts = [time_now.strftime("%Y%m%d%H%M%S")]

        # These seem like they would be nice to include.
        if 'prefix' in self.series:
            parts.append(self.series['prefix'])
        if 'postfix' in self.series:
            parts.append(self.series['postfix'])
        if 'version' in self.series:
            parts.append("v%s" % self.series['version'])

        parts.append(str(self.commit.count + 1))

        # The Change-Id must be last, right before the @
        parts.append(self.commit.change_id)

        # Join parts together with "." and write it out.
        outfd.write('Message-Id: <%s@changeid>\n' % '.'.join(parts))

    def process_stream(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 (io.IOBase): Input stream file object
            outfd (io.IOBase): 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/.*')

        self._write_message_id(outfd)

        while True:
            line = infd.readline()
            if not line:
                break
            out = self.process_line(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._add_warn("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.finalise()
        if self.insert_base_commit:
            if self.series.base_commit:
                print(f'base-commit: {self.series.base_commit.hash}',
                      file=outfd)
            if self.series.branch:
                print(f'branch: {self.series.branch}', file=outfd)


def insert_tags(msg, tags_to_emit):
    """Add extra tags to a commit message

    The tags are added after an existing block of tags if found, otherwise at
    the end.

    Args:
        msg (str): Commit message
        tags_to_emit (list): List of tags to emit, each a str

    Returns:
        (str) new message
    """
    out = []
    done = False
    emit_tags = False
    emit_blank = False
    for line in msg.splitlines():
        if not done:
            signoff_match = RE_SIGNOFF.match(line)
            tag_match = RE_TAG.match(line)
            if tag_match or signoff_match:
                emit_tags = True
            if emit_tags and not tag_match and not signoff_match:
                out += tags_to_emit
                emit_tags = False
                done = True
            emit_blank = not (signoff_match or tag_match)
        else:
            emit_blank = line
        out.append(line)
    if not done:
        if emit_blank:
            out.append('')
        out += tags_to_emit
    return '\n'.join(out)

def get_list(commit_range, git_dir=None, count=None):
    """Get a log of a list of comments

    This returns the output of 'git log' for the selected commits

    Args:
        commit_range (str): Range of commits to count (e.g. 'HEAD..base')
        git_dir (str): Path to git repositiory (None to use default)
        count (int): Number of commits to list, or None for no limit

    Returns
        str: String containing the contents of the git log
    """
    params = gitutil.log_cmd(commit_range, reverse=True, count=count,
                            git_dir=git_dir)
    return command.run_one(*params, capture=True).stdout

def get_metadata_for_list(commit_range, git_dir=None, count=None,
                          series=None, allow_overwrite=False):
    """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:
        commit_range (str): Range of commits to count (e.g. 'HEAD..base')
        git_dir (str): Path to git repositiory (None to use default)
        count (int): Number of commits to list, or None for no limit
        series (Series): Object to add information into. By default a new series
            is started.
        allow_overwrite (bool): Allow tags to overwrite an existing tag

    Returns:
        Series: Object containing information about the commits.
    """
    if not series:
        series = Series()
    series.allow_overwrite = allow_overwrite
    stdout = get_list(commit_range, git_dir, count)
    pst = PatchStream(series, is_log=True)
    for line in stdout.splitlines():
        pst.process_line(line)
    pst.finalise()
    return series

def get_metadata(branch, 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:
        branch (str): Branch to use (None for current branch)
        start (int): Commit to start from: 0=branch HEAD, 1=next one, etc.
        count (int): Number of commits to list

    Returns:
        Series: Object containing information about the commits.
    """
    top = f"{branch if branch else 'HEAD'}~{start}"
    series = get_metadata_for_list(top, None, count)
    series.base_commit = commit.Commit(gitutil.get_hash(f'{top}~{count}'))
    series.branch = branch or gitutil.get_branch()
    series.top = top
    return series

def get_metadata_for_test(text):
    """Process metadata from a file containing a git log. Used for tests

    Args:
        text:

    Returns:
        Series: Object containing information about the commits.
    """
    series = Series()
    pst = PatchStream(series, is_log=True)
    for line in text.splitlines():
        pst.process_line(line)
    pst.finalise()
    return series

def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False,
              insert_base_commit=False):
    """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:
        backup_dir (str): Path to directory to use to backup the file
        fname (str): Filename to patch file to process
        series (Series): Series information about this patch set
        cmt (Commit): Commit object for this patch file
        keep_change_id (bool): Keep the Change-Id tag.
        insert_base_commit (bool): True to add the base commit to the end

    Return:
        list: A list of errors, each str, or [] if all ok.
    """
    handle, tmpname = tempfile.mkstemp()
    outfd = os.fdopen(handle, 'w', encoding='utf-8')
    infd = open(fname, 'r', encoding='utf-8')
    pst = PatchStream(series, keep_change_id=keep_change_id,
                      insert_base_commit=insert_base_commit)
    pst.commit = cmt
    pst.process_stream(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 cmt.warn

def fix_patches(series, fnames, keep_change_id=False, insert_base_commit=False):
    """Fix up a list of patches identified by filenames

    The patch files are processed in place, and overwritten.

    Args:
        series (Series): The Series object
        fnames (:type: list of str): List of patch files to process
        keep_change_id (bool): Keep the Change-Id tag.
        insert_base_commit (bool): True to add the base commit to the end
    """
    # Current workflow creates patches, so we shouldn't need a backup
    backup_dir = None  #tempfile.mkdtemp('clean-patch')
    count = 0
    for fname in fnames:
        cmt = series.commits[count]
        cmt.patch = fname
        cmt.count = count
        result = fix_patch(backup_dir, fname, series, cmt,
                           keep_change_id=keep_change_id,
                           insert_base_commit=insert_base_commit)
        if result:
            print('%d warning%s for %s:' %
                  (len(result), 's' if len(result) > 1 else '', fname))
            for warn in result:
                print('\t%s' % warn)
            print()
        count += 1
    print('Cleaned %d patch%s' % (count, 'es' if count > 1 else ''))

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

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

    fil = open(fname, 'w')
    text = series.cover
    prefix = series.GetPatchPrefix()
    for line in lines:
        if line.startswith('Subject:'):
            # if more than 10 or 100 patches, it should say 00/xx, 000/xxx, etc
            zero_repeat = int(math.log10(count)) + 1
            zero = '0' * zero_repeat
            line = 'Subject: [%s %s/%d] %s\n' % (prefix, zero, 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)
        fil.write(line)

    # Insert the base commit and branch
    if series.base_commit:
        print(f'base-commit: {series.base_commit.hash}', file=fil)
    if series.branch:
        print(f'branch: {series.branch}', file=fil)

    fil.close()
