#
# SPDX-License-Identifier: GPL-2.0-only
#

import oe.path
import oe.types

class NotFoundError(bb.BBHandledException):
    def __init__(self, path):
        self.path = path

    def __str__(self):
        return "Error: %s not found." % self.path

class CmdError(bb.BBHandledException):
    def __init__(self, command, exitstatus, output):
        self.command = command
        self.status = exitstatus
        self.output = output

    def __str__(self):
        return "Command Error: '%s' exited with %d  Output:\n%s" % \
                (self.command, self.status, self.output)


def runcmd(args, dir = None):
    import pipes
    import subprocess

    if dir:
        olddir = os.path.abspath(os.curdir)
        if not os.path.exists(dir):
            raise NotFoundError(dir)
        os.chdir(dir)
        # print("cwd: %s -> %s" % (olddir, dir))

    try:
        args = [ pipes.quote(str(arg)) for arg in args ]
        cmd = " ".join(args)
        # print("cmd: %s" % cmd)
        (exitstatus, output) = subprocess.getstatusoutput(cmd)
        if exitstatus != 0:
            raise CmdError(cmd, exitstatus >> 8, output)
        if " fuzz " in output and "Hunk " in output:
            # Drop patch fuzz info with header and footer to log file so
            # insane.bbclass can handle to throw error/warning
            bb.note("--- Patch fuzz start ---\n%s\n--- Patch fuzz end ---" % format(output))

        return output

    finally:
        if dir:
            os.chdir(olddir)

class PatchError(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return "Patch Error: %s" % self.msg

class PatchSet(object):
    defaults = {
        "strippath": 1
    }

    def __init__(self, dir, d):
        self.dir = dir
        self.d = d
        self.patches = []
        self._current = None

    def current(self):
        return self._current

    def Clean(self):
        """
        Clean out the patch set.  Generally includes unapplying all
        patches and wiping out all associated metadata.
        """
        raise NotImplementedError()

    def Import(self, patch, force):
        if not patch.get("file"):
            if not patch.get("remote"):
                raise PatchError("Patch file must be specified in patch import.")
            else:
                patch["file"] = bb.fetch2.localpath(patch["remote"], self.d)

        for param in PatchSet.defaults:
            if not patch.get(param):
                patch[param] = PatchSet.defaults[param]

        if patch.get("remote"):
            patch["file"] = self.d.expand(bb.fetch2.localpath(patch["remote"], self.d))

        patch["filemd5"] = bb.utils.md5_file(patch["file"])

    def Push(self, force):
        raise NotImplementedError()

    def Pop(self, force):
        raise NotImplementedError()

    def Refresh(self, remote = None, all = None):
        raise NotImplementedError()

    @staticmethod
    def getPatchedFiles(patchfile, striplevel, srcdir=None):
        """
        Read a patch file and determine which files it will modify.
        Params:
            patchfile: the patch file to read
            striplevel: the strip level at which the patch is going to be applied
            srcdir: optional path to join onto the patched file paths
        Returns:
            A list of tuples of file path and change mode ('A' for add,
            'D' for delete or 'M' for modify)
        """

        def patchedpath(patchline):
            filepth = patchline.split()[1]
            if filepth.endswith('/dev/null'):
                return '/dev/null'
            filesplit = filepth.split(os.sep)
            if striplevel > len(filesplit):
                bb.error('Patch %s has invalid strip level %d' % (patchfile, striplevel))
                return None
            return os.sep.join(filesplit[striplevel:])

        for encoding in ['utf-8', 'latin-1']:
            try:
                copiedmode = False
                filelist = []
                with open(patchfile) as f:
                    for line in f:
                        if line.startswith('--- '):
                            patchpth = patchedpath(line)
                            if not patchpth:
                                break
                            if copiedmode:
                                addedfile = patchpth
                            else:
                                removedfile = patchpth
                        elif line.startswith('+++ '):
                            addedfile = patchedpath(line)
                            if not addedfile:
                                break
                        elif line.startswith('*** '):
                            copiedmode = True
                            removedfile = patchedpath(line)
                            if not removedfile:
                                break
                        else:
                            removedfile = None
                            addedfile = None

                        if addedfile and removedfile:
                            if removedfile == '/dev/null':
                                mode = 'A'
                            elif addedfile == '/dev/null':
                                mode = 'D'
                            else:
                                mode = 'M'
                            if srcdir:
                                fullpath = os.path.abspath(os.path.join(srcdir, addedfile))
                            else:
                                fullpath = addedfile
                            filelist.append((fullpath, mode))
            except UnicodeDecodeError:
                continue
            break
        else:
            raise PatchError('Unable to decode %s' % patchfile)

        return filelist


class PatchTree(PatchSet):
    def __init__(self, dir, d):
        PatchSet.__init__(self, dir, d)
        self.patchdir = os.path.join(self.dir, 'patches')
        self.seriespath = os.path.join(self.dir, 'patches', 'series')
        bb.utils.mkdirhier(self.patchdir)

    def _appendPatchFile(self, patch, strippath):
        with open(self.seriespath, 'a') as f:
            f.write(os.path.basename(patch) + "," + strippath + "\n")
        shellcmd = ["cat", patch, ">" , self.patchdir + "/" + os.path.basename(patch)]
        runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)

    def _removePatch(self, p):
        patch = {}
        patch['file'] = p.split(",")[0]
        patch['strippath'] = p.split(",")[1]
        self._applypatch(patch, False, True)

    def _removePatchFile(self, all = False):
        if not os.path.exists(self.seriespath):
            return
        with open(self.seriespath, 'r+') as f:
            patches = f.readlines()
        if all:
            for p in reversed(patches):
                self._removePatch(os.path.join(self.patchdir, p.strip()))
            patches = []
        else:
            self._removePatch(os.path.join(self.patchdir, patches[-1].strip()))
            patches.pop()
        with open(self.seriespath, 'w') as f:
            for p in patches:
                f.write(p)
         
    def Import(self, patch, force = None):
        """"""
        PatchSet.Import(self, patch, force)

        if self._current is not None:
            i = self._current + 1
        else:
            i = 0
        self.patches.insert(i, patch)

    def _applypatch(self, patch, force = False, reverse = False, run = True):
        shellcmd = ["cat", patch['file'], "|", "patch", "--no-backup-if-mismatch", "-p", patch['strippath']]
        if reverse:
            shellcmd.append('-R')

        if not run:
            return "sh" + "-c" + " ".join(shellcmd)

        if not force:
            shellcmd.append('--dry-run')

        try:
            output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)

            if force:
                return

            shellcmd.pop(len(shellcmd) - 1)
            output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
        except CmdError as err:
            raise bb.BBHandledException("Applying '%s' failed:\n%s" %
                                        (os.path.basename(patch['file']), err.output))

        if not reverse:
            self._appendPatchFile(patch['file'], patch['strippath'])

        return output

    def Push(self, force = False, all = False, run = True):
        bb.note("self._current is %s" % self._current)
        bb.note("patches is %s" % self.patches)
        if all:
            for i in self.patches:
                bb.note("applying patch %s" % i)
                self._applypatch(i, force)
                self._current = i
        else:
            if self._current is not None:
                next = self._current + 1
            else:
                next = 0

            bb.note("applying patch %s" % self.patches[next])
            ret = self._applypatch(self.patches[next], force)

            self._current = next
            return ret

    def Pop(self, force = None, all = None):
        if all:
            self._removePatchFile(True)
            self._current = None
        else:
            self._removePatchFile(False)

        if self._current == 0:
            self._current = None

        if self._current is not None:
            self._current = self._current - 1

    def Clean(self):
        """"""
        self.Pop(all=True)

class GitApplyTree(PatchTree):
    patch_line_prefix = '%% original patch'
    ignore_commit_prefix = '%% ignore'

    def __init__(self, dir, d):
        PatchTree.__init__(self, dir, d)
        self.commituser = d.getVar('PATCH_GIT_USER_NAME')
        self.commitemail = d.getVar('PATCH_GIT_USER_EMAIL')

    @staticmethod
    def extractPatchHeader(patchfile):
        """
        Extract just the header lines from the top of a patch file
        """
        for encoding in ['utf-8', 'latin-1']:
            lines = []
            try:
                with open(patchfile, 'r', encoding=encoding) as f:
                    for line in f:
                        if line.startswith('Index: ') or line.startswith('diff -') or line.startswith('---'):
                            break
                        lines.append(line)
            except UnicodeDecodeError:
                continue
            break
        else:
            raise PatchError('Unable to find a character encoding to decode %s' % patchfile)
        return lines

    @staticmethod
    def decodeAuthor(line):
        from email.header import decode_header
        authorval = line.split(':', 1)[1].strip().replace('"', '')
        result =  decode_header(authorval)[0][0]
        if hasattr(result, 'decode'):
            result = result.decode('utf-8')
        return result

    @staticmethod
    def interpretPatchHeader(headerlines):
        import re
        author_re = re.compile(r'[\S ]+ <\S+@\S+\.\S+>')
        from_commit_re = re.compile(r'^From [a-z0-9]{40} .*')
        outlines = []
        author = None
        date = None
        subject = None
        for line in headerlines:
            if line.startswith('Subject: '):
                subject = line.split(':', 1)[1]
                # Remove any [PATCH][oe-core] etc.
                subject = re.sub(r'\[.+?\]\s*', '', subject)
                continue
            elif line.startswith('From: ') or line.startswith('Author: '):
                authorval = GitApplyTree.decodeAuthor(line)
                # git is fussy about author formatting i.e. it must be Name <email@domain>
                if author_re.match(authorval):
                    author = authorval
                    continue
            elif line.startswith('Date: '):
                if date is None:
                    dateval = line.split(':', 1)[1].strip()
                    # Very crude check for date format, since git will blow up if it's not in the right
                    # format. Without e.g. a python-dateutils dependency we can't do a whole lot more
                    if len(dateval) > 12:
                        date = dateval
                continue
            elif not author and line.lower().startswith('signed-off-by: '):
                authorval = GitApplyTree.decodeAuthor(line)
                # git is fussy about author formatting i.e. it must be Name <email@domain>
                if author_re.match(authorval):
                    author = authorval
            elif from_commit_re.match(line):
                # We don't want the From <commit> line - if it's present it will break rebasing
                continue
            outlines.append(line)

        if not subject:
            firstline = None
            for line in headerlines:
                line = line.strip()
                if firstline:
                    if line:
                        # Second line is not blank, the first line probably isn't usable
                        firstline = None
                    break
                elif line:
                    firstline = line
            if firstline and not firstline.startswith(('#', 'Index:', 'Upstream-Status:')) and len(firstline) < 100:
                subject = firstline

        return outlines, author, date, subject

    @staticmethod
    def gitCommandUserOptions(cmd, commituser=None, commitemail=None, d=None):
        if d:
            commituser = d.getVar('PATCH_GIT_USER_NAME')
            commitemail = d.getVar('PATCH_GIT_USER_EMAIL')
        if commituser:
            cmd += ['-c', 'user.name="%s"' % commituser]
        if commitemail:
            cmd += ['-c', 'user.email="%s"' % commitemail]

    @staticmethod
    def prepareCommit(patchfile, commituser=None, commitemail=None):
        """
        Prepare a git commit command line based on the header from a patch file
        (typically this is useful for patches that cannot be applied with "git am" due to formatting)
        """
        import tempfile
        # Process patch header and extract useful information
        lines = GitApplyTree.extractPatchHeader(patchfile)
        outlines, author, date, subject = GitApplyTree.interpretPatchHeader(lines)
        if not author or not subject or not date:
            try:
                shellcmd = ["git", "log", "--format=email", "--follow", "--diff-filter=A", "--", patchfile]
                out = runcmd(["sh", "-c", " ".join(shellcmd)], os.path.dirname(patchfile))
            except CmdError:
                out = None
            if out:
                _, newauthor, newdate, newsubject = GitApplyTree.interpretPatchHeader(out.splitlines())
                if not author:
                    # If we're setting the author then the date should be set as well
                    author = newauthor
                    date = newdate
                elif not date:
                    # If we don't do this we'll get the current date, at least this will be closer
                    date = newdate
                if not subject:
                    subject = newsubject
        if subject and not (outlines and outlines[0].strip() == subject):
            outlines.insert(0, '%s\n\n' % subject.strip())

        # Write out commit message to a file
        with tempfile.NamedTemporaryFile('w', delete=False) as tf:
            tmpfile = tf.name
            for line in outlines:
                tf.write(line)
        # Prepare git command
        cmd = ["git"]
        GitApplyTree.gitCommandUserOptions(cmd, commituser, commitemail)
        cmd += ["commit", "-F", tmpfile]
        # git doesn't like plain email addresses as authors
        if author and '<' in author:
            cmd.append('--author="%s"' % author)
        if date:
            cmd.append('--date="%s"' % date)
        return (tmpfile, cmd)

    @staticmethod
    def extractPatches(tree, startcommit, outdir, paths=None):
        import tempfile
        import shutil
        tempdir = tempfile.mkdtemp(prefix='oepatch')
        try:
            shellcmd = ["git", "format-patch", "--no-signature", "--no-numbered", startcommit, "-o", tempdir]
            if paths:
                shellcmd.append('--')
                shellcmd.extend(paths)
            out = runcmd(["sh", "-c", " ".join(shellcmd)], tree)
            if out:
                for srcfile in out.split():
                    for encoding in ['utf-8', 'latin-1']:
                        patchlines = []
                        outfile = None
                        try:
                            with open(srcfile, 'r', encoding=encoding) as f:
                                for line in f:
                                    if line.startswith(GitApplyTree.patch_line_prefix):
                                        outfile = line.split()[-1].strip()
                                        continue
                                    if line.startswith(GitApplyTree.ignore_commit_prefix):
                                        continue
                                    patchlines.append(line)
                        except UnicodeDecodeError:
                            continue
                        break
                    else:
                        raise PatchError('Unable to find a character encoding to decode %s' % srcfile)

                    if not outfile:
                        outfile = os.path.basename(srcfile)
                    with open(os.path.join(outdir, outfile), 'w') as of:
                        for line in patchlines:
                            of.write(line)
        finally:
            shutil.rmtree(tempdir)

    def _applypatch(self, patch, force = False, reverse = False, run = True):
        import shutil

        def _applypatchhelper(shellcmd, patch, force = False, reverse = False, run = True):
            if reverse:
                shellcmd.append('-R')

            shellcmd.append(patch['file'])

            if not run:
                return "sh" + "-c" + " ".join(shellcmd)

            return runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)

        # Add hooks which add a pointer to the original patch file name in the commit message
        reporoot = (runcmd("git rev-parse --show-toplevel".split(), self.dir) or '').strip()
        if not reporoot:
            raise Exception("Cannot get repository root for directory %s" % self.dir)
        hooks_dir = os.path.join(reporoot, '.git', 'hooks')
        hooks_dir_backup = hooks_dir + '.devtool-orig'
        if os.path.lexists(hooks_dir_backup):
            raise Exception("Git hooks backup directory already exists: %s" % hooks_dir_backup)
        if os.path.lexists(hooks_dir):
            shutil.move(hooks_dir, hooks_dir_backup)
        os.mkdir(hooks_dir)
        commithook = os.path.join(hooks_dir, 'commit-msg')
        applyhook = os.path.join(hooks_dir, 'applypatch-msg')
        with open(commithook, 'w') as f:
            # NOTE: the formatting here is significant; if you change it you'll also need to
            # change other places which read it back
            f.write('echo "\n%s: $PATCHFILE" >> $1' % GitApplyTree.patch_line_prefix)
        os.chmod(commithook, 0o755)
        shutil.copy2(commithook, applyhook)
        try:
            patchfilevar = 'PATCHFILE="%s"' % os.path.basename(patch['file'])
            try:
                shellcmd = [patchfilevar, "git", "--work-tree=%s" % reporoot]
                self.gitCommandUserOptions(shellcmd, self.commituser, self.commitemail)
                shellcmd += ["am", "-3", "--keep-cr", "-p%s" % patch['strippath']]
                return _applypatchhelper(shellcmd, patch, force, reverse, run)
            except CmdError:
                # Need to abort the git am, or we'll still be within it at the end
                try:
                    shellcmd = ["git", "--work-tree=%s" % reporoot, "am", "--abort"]
                    runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
                except CmdError:
                    pass
                # git am won't always clean up after itself, sadly, so...
                shellcmd = ["git", "--work-tree=%s" % reporoot, "reset", "--hard", "HEAD"]
                runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
                # Also need to take care of any stray untracked files
                shellcmd = ["git", "--work-tree=%s" % reporoot, "clean", "-f"]
                runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)

                # Fall back to git apply
                shellcmd = ["git", "--git-dir=%s" % reporoot, "apply", "-p%s" % patch['strippath']]
                try:
                    output = _applypatchhelper(shellcmd, patch, force, reverse, run)
                except CmdError:
                    # Fall back to patch
                    output = PatchTree._applypatch(self, patch, force, reverse, run)
                # Add all files
                shellcmd = ["git", "add", "-f", "-A", "."]
                output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
                # Exclude the patches directory
                shellcmd = ["git", "reset", "HEAD", self.patchdir]
                output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
                # Commit the result
                (tmpfile, shellcmd) = self.prepareCommit(patch['file'], self.commituser, self.commitemail)
                try:
                    shellcmd.insert(0, patchfilevar)
                    output += runcmd(["sh", "-c", " ".join(shellcmd)], self.dir)
                finally:
                    os.remove(tmpfile)
                return output
        finally:
            shutil.rmtree(hooks_dir)
            if os.path.lexists(hooks_dir_backup):
                shutil.move(hooks_dir_backup, hooks_dir)


class QuiltTree(PatchSet):
    def _runcmd(self, args, run = True):
        quiltrc = self.d.getVar('QUILTRCFILE')
        if not run:
            return ["quilt"] + ["--quiltrc"] + [quiltrc] + args
        runcmd(["quilt"] + ["--quiltrc"] + [quiltrc] + args, self.dir)

    def _quiltpatchpath(self, file):
        return os.path.join(self.dir, "patches", os.path.basename(file))


    def __init__(self, dir, d):
        PatchSet.__init__(self, dir, d)
        self.initialized = False
        p = os.path.join(self.dir, 'patches')
        if not os.path.exists(p):
            os.makedirs(p)

    def Clean(self):
        try:
            self._runcmd(["pop", "-a", "-f"])
            oe.path.remove(os.path.join(self.dir, "patches","series"))
        except Exception:
            pass
        self.initialized = True

    def InitFromDir(self):
        # read series -> self.patches
        seriespath = os.path.join(self.dir, 'patches', 'series')
        if not os.path.exists(self.dir):
            raise NotFoundError(self.dir)
        if os.path.exists(seriespath):
            with open(seriespath, 'r') as f:
                for line in f.readlines():
                    patch = {}
                    parts = line.strip().split()
                    patch["quiltfile"] = self._quiltpatchpath(parts[0])
                    patch["quiltfilemd5"] = bb.utils.md5_file(patch["quiltfile"])
                    if len(parts) > 1:
                        patch["strippath"] = parts[1][2:]
                    self.patches.append(patch)

            # determine which patches are applied -> self._current
            try:
                output = runcmd(["quilt", "applied"], self.dir)
            except CmdError:
                import sys
                if sys.exc_value.output.strip() == "No patches applied":
                    return
                else:
                    raise
            output = [val for val in output.split('\n') if not val.startswith('#')]
            for patch in self.patches:
                if os.path.basename(patch["quiltfile"]) == output[-1]:
                    self._current = self.patches.index(patch)
        self.initialized = True

    def Import(self, patch, force = None):
        if not self.initialized:
            self.InitFromDir()
        PatchSet.Import(self, patch, force)
        oe.path.symlink(patch["file"], self._quiltpatchpath(patch["file"]), force=True)
        with open(os.path.join(self.dir, "patches", "series"), "a") as f:
            f.write(os.path.basename(patch["file"]) + " -p" + patch["strippath"] + "\n")
        patch["quiltfile"] = self._quiltpatchpath(patch["file"])
        patch["quiltfilemd5"] = bb.utils.md5_file(patch["quiltfile"])

        # TODO: determine if the file being imported:
        #      1) is already imported, and is the same
        #      2) is already imported, but differs

        self.patches.insert(self._current or 0, patch)


    def Push(self, force = False, all = False, run = True):
        # quilt push [-f]

        args = ["push"]
        if force:
            args.append("-f")
        if all:
            args.append("-a")
        if not run:
            return self._runcmd(args, run)

        self._runcmd(args)

        if self._current is not None:
            self._current = self._current + 1
        else:
            self._current = 0

    def Pop(self, force = None, all = None):
        # quilt pop [-f]
        args = ["pop"]
        if force:
            args.append("-f")
        if all:
            args.append("-a")

        self._runcmd(args)

        if self._current == 0:
            self._current = None

        if self._current is not None:
            self._current = self._current - 1

    def Refresh(self, **kwargs):
        if kwargs.get("remote"):
            patch = self.patches[kwargs["patch"]]
            if not patch:
                raise PatchError("No patch found at index %s in patchset." % kwargs["patch"])
            (type, host, path, user, pswd, parm) = bb.fetch.decodeurl(patch["remote"])
            if type == "file":
                import shutil
                if not patch.get("file") and patch.get("remote"):
                    patch["file"] = bb.fetch2.localpath(patch["remote"], self.d)

                shutil.copyfile(patch["quiltfile"], patch["file"])
            else:
                raise PatchError("Unable to do a remote refresh of %s, unsupported remote url scheme %s." % (os.path.basename(patch["quiltfile"]), type))
        else:
            # quilt refresh
            args = ["refresh"]
            if kwargs.get("quiltfile"):
                args.append(os.path.basename(kwargs["quiltfile"]))
            elif kwargs.get("patch"):
                args.append(os.path.basename(self.patches[kwargs["patch"]]["quiltfile"]))
            self._runcmd(args)

class Resolver(object):
    def __init__(self, patchset, terminal):
        raise NotImplementedError()

    def Resolve(self):
        raise NotImplementedError()

    def Revert(self):
        raise NotImplementedError()

    def Finalize(self):
        raise NotImplementedError()

class NOOPResolver(Resolver):
    def __init__(self, patchset, terminal):
        self.patchset = patchset
        self.terminal = terminal

    def Resolve(self):
        olddir = os.path.abspath(os.curdir)
        os.chdir(self.patchset.dir)
        try:
            self.patchset.Push()
        except Exception:
            import sys
            os.chdir(olddir)
            raise

# Patch resolver which relies on the user doing all the work involved in the
# resolution, with the exception of refreshing the remote copy of the patch
# files (the urls).
class UserResolver(Resolver):
    def __init__(self, patchset, terminal):
        self.patchset = patchset
        self.terminal = terminal

    # Force a push in the patchset, then drop to a shell for the user to
    # resolve any rejected hunks
    def Resolve(self):
        olddir = os.path.abspath(os.curdir)
        os.chdir(self.patchset.dir)
        try:
            self.patchset.Push(False)
        except CmdError as v:
            # Patch application failed
            patchcmd = self.patchset.Push(True, False, False)

            t = self.patchset.d.getVar('T')
            if not t:
                bb.msg.fatal("Build", "T not set")
            bb.utils.mkdirhier(t)
            import random
            rcfile = "%s/bashrc.%s.%s" % (t, str(os.getpid()), random.random())
            with open(rcfile, "w") as f:
                f.write("echo '*** Manual patch resolution mode ***'\n")
                f.write("echo 'Dropping to a shell, so patch rejects can be fixed manually.'\n")
                f.write("echo 'Run \"quilt refresh\" when patch is corrected, press CTRL+D to exit.'\n")
                f.write("echo ''\n")
                f.write(" ".join(patchcmd) + "\n")
            os.chmod(rcfile, 0o775)

            self.terminal("bash --rcfile " + rcfile, 'Patch Rejects: Please fix patch rejects manually', self.patchset.d)

            # Construct a new PatchSet after the user's changes, compare the
            # sets, checking patches for modifications, and doing a remote
            # refresh on each.
            oldpatchset = self.patchset
            self.patchset = oldpatchset.__class__(self.patchset.dir, self.patchset.d)

            for patch in self.patchset.patches:
                oldpatch = None
                for opatch in oldpatchset.patches:
                    if opatch["quiltfile"] == patch["quiltfile"]:
                        oldpatch = opatch

                if oldpatch:
                    patch["remote"] = oldpatch["remote"]
                    if patch["quiltfile"] == oldpatch["quiltfile"]:
                        if patch["quiltfilemd5"] != oldpatch["quiltfilemd5"]:
                            bb.note("Patch %s has changed, updating remote url %s" % (os.path.basename(patch["quiltfile"]), patch["remote"]))
                            # user change?  remote refresh
                            self.patchset.Refresh(remote=True, patch=self.patchset.patches.index(patch))
                        else:
                            # User did not fix the problem.  Abort.
                            raise PatchError("Patch application failed, and user did not fix and refresh the patch.")
        except Exception:
            os.chdir(olddir)
            raise
        os.chdir(olddir)


def patch_path(url, fetch, workdir, expand=True):
    """Return the local path of a patch, or return nothing if this isn't a patch"""

    local = fetch.localpath(url)
    if os.path.isdir(local):
        return
    base, ext = os.path.splitext(os.path.basename(local))
    if ext in ('.gz', '.bz2', '.xz', '.Z'):
        if expand:
            local = os.path.join(workdir, base)
        ext = os.path.splitext(base)[1]

    urldata = fetch.ud[url]
    if "apply" in urldata.parm:
        apply = oe.types.boolean(urldata.parm["apply"])
        if not apply:
            return
    elif ext not in (".diff", ".patch"):
        return

    return local

def src_patches(d, all=False, expand=True):
    workdir = d.getVar('WORKDIR')
    fetch = bb.fetch2.Fetch([], d)
    patches = []
    sources = []
    for url in fetch.urls:
        local = patch_path(url, fetch, workdir, expand)
        if not local:
            if all:
                local = fetch.localpath(url)
                sources.append(local)
            continue

        urldata = fetch.ud[url]
        parm = urldata.parm
        patchname = parm.get('pname') or os.path.basename(local)

        apply, reason = should_apply(parm, d)
        if not apply:
            if reason:
                bb.note("Patch %s %s" % (patchname, reason))
            continue

        patchparm = {'patchname': patchname}
        if "striplevel" in parm:
            striplevel = parm["striplevel"]
        elif "pnum" in parm:
            #bb.msg.warn(None, "Deprecated usage of 'pnum' url parameter in '%s', please use 'striplevel'" % url)
            striplevel = parm["pnum"]
        else:
            striplevel = '1'
        patchparm['striplevel'] = striplevel

        patchdir = parm.get('patchdir')
        if patchdir:
            patchparm['patchdir'] = patchdir

        localurl = bb.fetch.encodeurl(('file', '', local, '', '', patchparm))
        patches.append(localurl)

    if all:
        return sources

    return patches


def should_apply(parm, d):
    import bb.utils
    if "mindate" in parm or "maxdate" in parm:
        pn = d.getVar('PN')
        srcdate = d.getVar('SRCDATE_%s' % pn)
        if not srcdate:
            srcdate = d.getVar('SRCDATE')

        if srcdate == "now":
            srcdate = d.getVar('DATE')

        if "maxdate" in parm and parm["maxdate"] < srcdate:
            return False, 'is outdated'

        if "mindate" in parm and parm["mindate"] > srcdate:
            return False, 'is predated'


    if "minrev" in parm:
        srcrev = d.getVar('SRCREV')
        if srcrev and srcrev < parm["minrev"]:
            return False, 'applies to later revisions'

    if "maxrev" in parm:
        srcrev = d.getVar('SRCREV')
        if srcrev and srcrev > parm["maxrev"]:
            return False, 'applies to earlier revisions'

    if "rev" in parm:
        srcrev = d.getVar('SRCREV')
        if srcrev and parm["rev"] not in srcrev:
            return False, "doesn't apply to revision"

    if "notrev" in parm:
        srcrev = d.getVar('SRCREV')
        if srcrev and parm["notrev"] in srcrev:
            return False, "doesn't apply to revision"

    if "maxver" in parm:
        pv = d.getVar('PV')
        if bb.utils.vercmp_string_op(pv, parm["maxver"], ">"):
            return False, "applies to earlier version"

    if "minver" in parm:
        pv = d.getVar('PV')
        if bb.utils.vercmp_string_op(pv, parm["minver"], "<"):
            return False, "applies to later version"

    return True, None

