#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# This bot automatically recognizes when patchwork-tracked patches
# are applied to git repositories and marks them as "Accepted." It can
# additionally send mail notifications to the maintainers and to the
# patch submitters.
#
# It runs from a cronjob, but can be also run from post-update hooks with
# extra wrappers. For more details, consult:
#
# https://korg.wiki.kernel.org/userdoc/pwbot
#
#

__author__ = 'Konstantin Ryabitsev <konstantin@linuxfoundation.org>'

import os
import sys
import argparse
import smtplib
import subprocess
import sqlite3
import logging
import hashlib
import re
import requests
import datetime

import ruamel.yaml # noqa

from email.mime.text import MIMEText
from email.header import Header
from email.utils import formatdate, getaddresses, make_msgid

from fcntl import lockf, LOCK_EX, LOCK_NB

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

from string import Template
from typing import Optional, Tuple, Union, Dict, List, Set

# Send all email 8-bit, this is not 1999
from email import charset
charset.add_charset('utf-8', charset.SHORTEST)

__VERSION__ = '2.0'
DB_VERSION = 1
REST_API_VERSION = '1.2'
LORE_RE = re.compile(r'^\s*Link:\s+\S+://(?:lore|lkml)\.kernel\.org\S*/([^@]+@[^@\s/]+)$', flags=re.M | re.I)
HUNK_RE = re.compile(r'^@@ -\d+(?:,(\d+))? \+\d+(?:,(\d+))? @@')
FILENAME_RE = re.compile(r'^(---|\+\+\+) (\S+)')
REST_PER_PAGE = 100

CONFIG = None

NOMAIL = False
DRYRUN = False
MAILHOST = 'localhost'
DOMAIN = None
CACHEDIR = os.path.expanduser('~/.cache/git-patchwork-bot')

_project_cache = dict()
_server_cache = dict()
_rev_cache = dict()

logger = logging.getLogger('gitpwcron')


class Restmaker:
    server: str
    url: str
    series_url: str
    patches_url: str
    projects_url: str
    session: requests.Session
    _patches: Dict[int, Optional[dict]]

    def __init__(self, server: str) -> None:
        self.server = server
        self.url = '/'.join((server.rstrip('/'), 'api', REST_API_VERSION))

        self.series_url = '/'.join((self.url, 'series'))
        self.patches_url = '/'.join((self.url, 'patches'))
        self.covers_url = '/'.join((self.url, 'covers'))
        self.projects_url = '/'.join((self.url, 'projects'))

        # Simple local cache
        self._patches = dict()

        self.session = requests.session()
        retry = Retry(connect=3, backoff_factor=0.5)
        adapter = HTTPAdapter(max_retries=retry)
        self.session.mount('http://', adapter)
        self.session.mount('https://', adapter)
        headers = {
            'User-Agent': f'git-patchwork-bot/{__VERSION__}',
        }
        apitoken = CONFIG['patchworks'][server].get('apitoken', None)
        if not apitoken:
            logger.critical('We require an apitoken for anything to work')
            sys.exit(1)
        headers['Authorization'] = f'Token {apitoken}'
        self.session.headers.update(headers)

    def get_unpaginated(self, url: str, params: list) -> List[dict]:
        # Caller should catch RequestException
        page = 0
        results = list()
        params.append(('per_page', REST_PER_PAGE))
        _page_params = list(params)
        while True:
            page += 1
            logger.debug('Processing page %s', page)
            _params = list(params) + [('page', page)]
            logger.debug('Performing query: url=%s, params=%s', url, _params)
            rsp = self.session.get(url, params=_params, stream=False)
            rsp.raise_for_status()
            pagedata = rsp.json()
            if not pagedata:
                break
            results.extend(pagedata)
            if len(pagedata) < REST_PER_PAGE:
                break

        return results

    def get_cover(self, cover_id: int) -> dict:
        try:
            logger.debug('Grabbing cover %d', cover_id)
            url = '/'.join((self.covers_url, str(cover_id), ''))
            logger.debug('url=%s', url)
            rsp = self.session.get(url, stream=False)
            rsp.raise_for_status()
            return rsp.json()
        except requests.exceptions.RequestException as ex:
            logger.info('REST error: %s', ex)
            raise KeyError('Not able to get cover %s', cover_id)

    def get_patch(self, patch_id: int) -> dict:
        if patch_id not in self._patches:
            try:
                logger.debug('Grabbing patch %d', patch_id)
                url = '/'.join((self.patches_url, str(patch_id), ''))
                logger.debug('url=%s', url)
                rsp = self.session.get(url, stream=False)
                rsp.raise_for_status()
                self._patches[patch_id] = rsp.json()
            except requests.exceptions.RequestException as ex:
                logger.info('REST error: %s', ex)
                self._patches[patch_id] = None
                raise KeyError('Not able to get patch_id %s', patch_id)

        return self._patches[patch_id]

    def get_series(self, series_id: int) -> dict:
        try:
            logger.debug('Grabbing series %d', series_id)
            url = '/'.join((self.series_url, str(series_id), ''))
            logger.debug('url=%s', url)
            rsp = self.session.get(url, stream=False)
            rsp.raise_for_status()
            return rsp.json()
        except requests.exceptions.RequestException as ex:
            logger.info('REST error: %s', ex)
            raise KeyError('Not able to get series %s', series_id)

    def get_patches_list(self, params: list, unpaginated: bool = True) -> List[dict]:
        try:
            if unpaginated:
                return self.get_unpaginated(self.patches_url, params)
            else:
                rsp = self.session.get(self.patches_url, params=params, stream=False)
                rsp.raise_for_status()
                return rsp.json()
        except requests.exceptions.RequestException as ex:
            logger.info('REST error: %s', ex)
            return list()

    def get_series_list(self, params: list, unpaginated: bool = True) -> List[dict]:
        try:
            if unpaginated:
                return self.get_unpaginated(self.series_url, params)
            else:
                rsp = self.session.get(self.series_url, params=params, stream=False)
                rsp.raise_for_status()
                return rsp.json()
        except requests.exceptions.RequestException as ex:
            logger.info('REST error: %s', ex)
            return list()

    def get_projects_list(self, params: list) -> list:
        try:
            return self.get_unpaginated(self.projects_url, params)
        except requests.exceptions.RequestException as ex:
            logger.info('REST error: %s', ex)
            return list()

    def update_patch(self, patch_id: int, state: Optional[str] = None, archived: bool = False,
                     commit_ref: Optional[str] = None) -> list:
        # Clear it out of the cache
        if patch_id in self._patches:
            del self._patches[patch_id]

        try:
            logger.debug('Updating patch %d:', patch_id)
            url = '/'.join((self.patches_url, str(patch_id), ''))
            logger.debug('url=%s', url)
            data = list()
            if state is not None:
                logger.debug('  state=%s', state)
                data.append(('state', state))
            if archived:
                logger.debug('  archived=True')
                data.append(('archived', True))
            if commit_ref is not None:
                logger.debug('  commit_ref=%s', commit_ref)
                data.append(('commit_ref', commit_ref))

            rsp = self.session.patch(url, data=data, stream=False)
            rsp.raise_for_status()
        except requests.exceptions.RequestException as ex:
            logger.info('REST error: %s', ex)
            raise RuntimeError('Unable to update patch %s', patch_id)

        return rsp.json()


def get_patchwork_patches_by_project_hash(rm: Restmaker, project: int, pwhash: str) -> List[int]:
    logger.debug('Looking up hash=%s', pwhash)
    params = [
        ('project', project),
        ('archived', 'false'),
        ('hash', pwhash),
    ]
    patches = rm.get_patches_list(params)
    if not patches:
        logger.debug('No match for hash=%s', pwhash)
        return list()

    return [patch['id'] for patch in patches]


def get_patchwork_patches_by_project_msgid(rm: Restmaker, project: int, msgid: str) -> List[int]:
    logger.debug('Looking up msgid=%s', msgid)
    params = [
        ('project', project),
        ('archived', 'false'),
        ('msgid', msgid),
    ]
    patches = rm.get_patches_list(params)
    if not patches:
        logger.debug('No match for msgid=%s', msgid)
        return list()

    return [patch['id'] for patch in patches]


def get_patchwork_pull_requests_by_project(rm: Restmaker, project: int, fromstate: List[str]) -> Set[Tuple]:
    params = [
        ('project', project),
        ('archived', 'false'),
        ('state', fromstate),
        ('order', '-date'),
        ('q', 'PULL'),
    ]
    prs = set()
    results = rm.get_patches_list(params)
    if not results:
        return prs
    for entry in results:
        pull_url = entry.get('pull_url')
        if pull_url:
            patch_id = entry.get('id')
            logger.info('Found pull request: %s (%s)', pull_url, patch_id)
            chunks = pull_url.split()
            pull_host = chunks[0]
            if len(chunks) > 1:
                pull_refname = chunks[1]
            else:
                pull_refname = 'master'

            prs.add((pull_host, pull_refname, patch_id))
    return prs


def project_by_name(pname: str) -> Tuple:
    global _project_cache
    global _server_cache

    if not pname:
        raise KeyError('Must specify project name')

    if pname not in _project_cache:
        # Find patchwork definition containing this project
        server = None
        pconfig = None
        for defurl in CONFIG['patchworks']:
            if pname in CONFIG['patchworks'][defurl]['projects']:
                server = defurl
                pconfig = CONFIG['patchworks'][defurl]['projects'][pname]
                break
        if not server:
            logger.critical('Could not find project matching %s in config', pname)
            sys.exit(1)

        if server not in _server_cache:
            rm = Restmaker(server)
            _project_cache[server] = dict()
            params = list()
            plist = rm.get_projects_list(params)
            if not plist:
                logger.info('Unable to get project list on %s', server)
                sys.exit(1)

            _server_cache[server] = (rm, plist)
        else:
            rm, plist = _server_cache[server]

        found = False
        for project in plist:
            if project['link_name'].lower().startswith(pname.lower()):
                logger.debug('project lookup: linkname=%s, server=%s, id=%d', pname, server, project['id'])
                _project_cache[pname] = (project, rm, pconfig)
                found = True
                break
        if not found:
            logger.info('Could not find project matching %s on server %s', pname, server)
            raise KeyError(f'No match for project {pname} on server {server}')

    return _project_cache[pname]


def db_save_meta(c: sqlite3.Cursor) -> None:
    c.execute('DELETE FROM meta')
    c.execute('''INSERT INTO meta VALUES(?)''', (DB_VERSION,))


def db_save_repo_heads(c: sqlite3.Cursor, heads: list) -> None:
    c.execute('DELETE FROM heads')
    for refname, commit_id in heads:
        c.execute('''INSERT INTO heads VALUES(?,?)''', (refname, commit_id))


def db_get_repo_heads(c: sqlite3.Cursor) -> List[Tuple]:
    return c.execute('SELECT refname, commit_id FROM heads').fetchall()


def db_init_common_sqlite_db(c: sqlite3.Cursor) -> None:
    c.execute('''
        CREATE TABLE meta (
            version INTEGER
        )''')
    db_save_meta(c)


def db_init_pw_sqlite_db(c: sqlite3.Cursor) -> None:
    logger.info('Initializing new sqlite3 db with metadata version %s', DB_VERSION)
    db_init_common_sqlite_db(c)
    c.execute('''
        CREATE TABLE heads (
            refname TEXT,
            commit_id TEXT
        )''')


def git_get_command_lines(gitdir: str, args: List[str]) -> list:
    out = git_run_command(gitdir, args)
    lines = list()
    if out:
        for line in out.split('\n'):
            if line == '':
                continue
            lines.append(line)

    return lines


def git_run_command(gitdir: str, args: List[str], stdin: Optional[str] = None) -> str:
    args = ['git', '--no-pager', '--git-dir', gitdir] + args

    logger.debug('Running %s' % ' '.join(args))

    if stdin is None:
        (output, error) = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    else:
        pp = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        (output, error) = pp.communicate(input=stdin.encode('utf-8'))

    output = output.strip().decode('utf-8', errors='replace')
    if len(error.strip()):
        logger.debug('Stderr: %s', error.decode('utf-8', errors='replace'))

    return output


def git_get_repo_heads(gitdir: str, branch: str, ancestry: Optional[str] = None) -> List[Tuple[str, str]]:
    refs = list()
    lines = git_get_command_lines(gitdir, ['show-ref', branch])
    if ancestry is None:
        ancestry = ''
    else:
        ancestry = f'~{ancestry}'
    if lines is not None:
        for line in lines:
            (commit_id, refname) = line.split()
            refs.append((refname, commit_id + ancestry))
    return refs


def git_get_new_revs(gitdir: str, db_heads: List[Tuple[str, str]], git_heads: List[Tuple[str, str]],
                     committers: List[str], merges: bool = False) -> Dict[str, list]:
    newrevs = dict()
    if committers:
        logger.debug('filtering by committers=%s', committers)
    for db_refrow in list(db_heads):
        if db_refrow in git_heads:
            logger.debug('No changes in %s', db_refrow[0])
            continue

        (refname, db_commit_id) = db_refrow
        # Find a matching one in git
        git_commit_id = None
        for git_refrow in git_heads:
            if git_refrow[0] == refname:
                git_commit_id = git_refrow[1]
                break
        if git_commit_id is None:
            # Looks like this head is gone from git
            db_heads.remove(db_refrow)
            continue

        if db_commit_id == git_commit_id:
            # No changes in this head
            continue

        rev_range = '%s..%s' % (db_commit_id, git_commit_id)
        args = ['log', '--pretty=%H:%cn:%ce:%s', '--reverse']
        if not merges:
            args += ['--no-merges']

        args += [rev_range, refname]

        lines = git_get_command_lines(gitdir, args)
        if not lines:
            continue

        revs = list()

        for line in lines:
            (commit_id, cn, ce, logmsg) = line.split(':', 3)
            if committers and ce not in committers:
                logger.debug('Skipping %s, ce=%s', commit_id, ce)
                continue
            if len(cn):
                committer = '%s <%s>' % (cn, ce)
            else:
                committer = ce
            logger.debug('commit_id=%s, committer=%s, subject=%s', commit_id, committer, logmsg)
            revs.append((commit_id, logmsg, committer))

        if revs:
            newrevs[refname] = revs

    return newrevs


def git_get_rev_info(gitdir: str, rev: str) -> str:
    args = ['show', rev]
    return git_run_command(gitdir, args)


def git_get_patch_id(diff: str) -> Optional[str]:
    args = ['patch-id', '--stable']
    out = git_run_command('', args, stdin=diff)
    logger.debug('out=%s', out)
    if not out:
        return None
    return out.split()[0]


def get_patchwork_hash(diff: str) -> str:
    """Generate a hash from a diff. Lifted near verbatim from patchwork."""

    # normalise spaces
    diff = diff.replace('\r', '')
    diff = diff.strip() + '\n'

    prefixes = ['-', '+', ' ']
    hashed = hashlib.sha1()

    inpatch = False
    for line in diff.split('\n'):
        if len(line) <= 0:
            continue
        # Ignore any content before "^diff "
        if not inpatch and not line.startswith('diff '):
            continue

        inpatch = True

        hunk_match = HUNK_RE.match(line)
        filename_match = FILENAME_RE.match(line)

        if filename_match:
            # normalise -p1 top-directories
            if filename_match.group(1) == '---':
                filename = 'a/'
            else:
                filename = 'b/'
            filename += '/'.join(filename_match.group(2).split('/')[1:])

            line = filename_match.group(1) + ' ' + filename
        elif hunk_match:
            # remove line numbers, but leave line counts
            def fn(x):
                if not x:
                    return 1
                return int(x)
            line_nos = list(map(fn, hunk_match.groups()))
            line = '@@ -%d +%d @@' % tuple(line_nos)
        elif line[0] in prefixes:
            # if we have a +, - or context line, leave as-is
            pass
        else:
            # other lines are ignored
            continue

        hashed.update((line + '\n').encode('utf-8'))

    return hashed.hexdigest()


def listify(obj: Union[str, list, None]) -> list:
    if isinstance(obj, list):
        return list(obj)
    return [obj]


def send_summary(serieslist: List[dict], committers: Dict[int, str], to_state: str, refname: str, revs: Dict[int, str],
                 pname: str, rs: Dict[str, str], hs: Dict[str, str]) -> str:
    logger.info('Preparing summary')
    # we send summaries by project, so the project name is going to be all the same

    count = 0
    summary = list()
    for sdata in serieslist:
        count += 1
        logger.debug('Summarizing: %s', sdata.get('name'))

        # If we have a cover letter, then the reference is the msgid of the cover letter,
        # else the reference is the msgid of the first patch
        patches = sdata.get('patches')

        submitter = sdata.get('submitter')

        if len(patches) == 1:
            summary.append('Patch: %s' % sdata.get('name'))
        else:
            summary.append('Series: %s' % sdata.get('name'))

        summary.append('  Submitter: %s <%s>' % (submitter.get('name'), submitter.get('email')))
        pid = patches[0].get('id')
        if pid in committers:
            summary.append('  Committer: %s' % committers[pid])
        summary.append('  Patchwork: %s' % sdata.get('web_url'))

        if sdata.get('cover_letter'):
            msgid = sdata.get('cover_letter').get('msgid').strip('<>')
        else:
            msgid = patches[0].get('msgid').strip('<>')

        link = 'https://lore.kernel.org/r/%s' % msgid
        summary.append('  Lore link: %s' % link)

        if len(patches) > 1:
            summary.append('    Patches: %s' % patches[0].get('name'))
            for patch in patches[1:]:
                pid = patch.get('id')
                if pid in revs:
                    count += 1
                    summary.append('             %s' % patch.get('name'))
        summary.append('')

    bodytpt = Template(CONFIG['templates']['summary'])
    params = {
        'newstate': to_state,
        'treename': rs['treename'],
        'refname': refname.replace('refs/heads/', '', 1),
        'summary': '\n'.join(summary),
        'total': count,
        'signature': CONFIG['templates']['signature'],
    }
    body = bodytpt.safe_substitute(params)

    project, rm, pconfig = project_by_name(pname)
    tweaks = get_tweaks(pconfig, hs)

    msg = MIMEText(body, _charset='utf-8')
    msg.replace_header('Content-Transfer-Encoding', '8bit')

    msg['Subject'] = Header('Patchwork summary for: %s' % pname)
    msg['From'] = Header(tweaks['from'])
    msg['Message-Id'] = make_msgid('git-patchwork-summary', domain=DOMAIN)
    msg['Date'] = formatdate(localtime=True)

    targets = listify(tweaks['summaryto'])
    msg['To'] = Header(', '.join(targets))
    if 'alwayscc' in tweaks:
        msg['Cc'] = Header(', '.join(listify(tweaks['alwayscc'])))
        targets.append(listify(tweaks['alwayscc']))
    if 'alwaysbcc' in tweaks:
        targets.append(listify(tweaks['alwaysbcc']))

    if not NOMAIL:
        logger.debug('Message follows')
        logger.debug(msg.as_string())
        logger.info('Sending summary to: %s', msg['To'])

        smtp = smtplib.SMTP(MAILHOST)
        smtp.sendmail(tweaks['from'], targets, msg.as_bytes())
        smtp.close()
    else:
        logger.info('Would have sent the following:')
        logger.info('------------------------------')
        logger.info(msg.as_string())
        logger.info('------------------------------')

    return str(msg['Message-Id'])


def get_tweaks(pconfig: Dict[str, str], hconfig: Dict[str, str]) -> Dict[str, str]:
    fields = ['from', 'summaryto', 'onlyto', 'neverto', 'onlyifcc', 'neverifcc',
              'alwayscc', 'alwaysbcc', 'cclist', 'ccall']
    bubbled = dict()
    for field in fields:
        if field in hconfig:
            bubbled[field] = hconfig[field]
            continue
        if field in pconfig:
            bubbled[field] = pconfig[field]
    return bubbled


def notify_submitters(serieslist: List[dict], committers: Dict[int, str], refname: str,
                      revs: Dict[int, str], pname: str, rs: Dict[str, Union[str, list, dict]],
                      hs: Dict[str, Union[str, list, dict]]) -> None:
    logger.info('Sending submitter notifications')
    project, rm, pconfig = project_by_name(pname)

    tweaks = get_tweaks(pconfig, hs)

    for sdata in serieslist:
        # If we have a cover letter, then the reference is the msgid of the cover letter,
        # else the reference is the msgid of the first patch
        patches = sdata.get('patches')
        is_pull_request = False
        content = headers = reference = None
        if sdata.get('cover_letter'):
            reference = sdata.get('cover_letter').get('msgid')
            try:
                fullcover = rm.get_cover(sdata.get('cover_letter').get('id'))
                headers = {k.lower(): v for k, v in fullcover.get('headers').items()}
                content = fullcover.get('content')
            except KeyError:
                logger.debug('Unable to get cover letter, will try first patch')
        if not reference:
            reference = patches[0].get('msgid')
            try:
                fullpatch = rm.get_patch(patches[0].get('id'))
                headers = {k.lower(): v for k, v in fullpatch.get('headers').items()}
                content = fullpatch.get('content')
                if fullpatch.get('pull_url'):
                    is_pull_request = True
            except KeyError:
                logger.debug('Unable to get first patch reference, bailing on %s', sdata.get('id'))
                continue

        submitter = sdata.get('submitter')
        project = sdata.get('project')

        if 'neverto' in tweaks:
            neverto = listify(tweaks['neverto'])
            if submitter.get('email') in neverto:
                logger.debug('Skipping neverto address:%s', submitter.get('email'))
                continue

        ccs = list()
        cchdr = headers.get('cc')
        if cchdr:
            ccs = [chunk[1] for chunk in getaddresses(listify(cchdr))]
        tos = list()
        tohdr = headers.get('to')
        if tohdr:
            tos = [chunk[1] for chunk in getaddresses(listify(tohdr))]

        xpb = headers.get('x-patchwork-bot')
        logger.debug('X-Patchwork-Bot=%s', xpb)
        # If X-Patchwork-Bot header is set to "notify" we always notify
        if xpb != 'notify':
            # Use cc-based notification logic
            if 'onlyifcc' in tweaks:
                match = None
                for chunk in listify(tweaks['onlyifcc']):
                    if chunk in ccs:
                        match = chunk
                        break
                if match is None:
                    logger.debug('Skipping %s due to onlyifcc=%s', submitter.get('email'), tweaks['onlyifcc'])
                    continue

            if ccs and 'neverifcc' in tweaks:
                match = None
                for chunk in listify(tweaks['neverifcc']):
                    if chunk in ccs:
                        match = chunk
                        break
                if match is not None:
                    logger.debug('Skipping %s due to neverifcc=%s', submitter.get('email'), tweaks['neverifcc'])
                    continue

        logger.debug('Preparing a notification for %s', submitter.get('email'))
        if is_pull_request:
            reqtype = 'pull request'
        elif len(sdata.get('patches')) > 1:
            reqtype = 'series'
        else:
            reqtype = 'patch'

        trimquote = list()
        if content:
            qcount = 0
            for cline in content.split('\n'):
                # Quote the first paragraph only and then [snip] if we quoted more than 5 lines
                if qcount > 5 and (not len(cline.strip()) or cline.strip().find('---') == 0):
                    trimquote.append('> ')
                    trimquote.append('> [...]')
                    break
                trimquote.append('> %s' % cline.rstrip())
                qcount += 1

        summary = list()
        committer = 'unknown committer'
        for patch in patches:
            summary.append('  - %s' % patch.get('name'))
            pid = patch.get('id')
            if pid in revs:
                committer = committers.get(pid, 'unknown committer')
                if 'commitlink' in rs:
                    summary.append('    %s' % (rs['commitlink'] % revs[pid]))
            else:
                summary.append('    (no matching commit)')

        bodytpt = Template(CONFIG['templates']['submitter'])
        params = {
            'reqtype': reqtype,
            'treename': rs['treename'],
            'refname': refname.replace('refs/heads/', '', 1),
            'committer': committer,
            'sentdate': str(headers.get('date')),
            'trimquote': '\n'.join(trimquote),
            'summary': '\n'.join(summary),
            'signature': CONFIG['templates']['signature'],
        }

        body = bodytpt.safe_substitute(params)

        msg = MIMEText(body, _charset='utf-8')
        msg.replace_header('Content-Transfer-Encoding', '8bit')

        msg['Subject'] = Header('Re: %s' % headers.get('subject'))
        msg['From'] = Header(tweaks['from'])
        msg['Message-Id'] = make_msgid('git-patchwork-notify', domain=DOMAIN)
        msg['Date'] = formatdate(localtime=True)
        msg['References'] = Header(reference)
        msg['In-Reply-To'] = Header(reference)

        if 'onlyto' in tweaks:
            targets = listify(tweaks['onlyto'])
            msg['To'] = '%s <%s>' % (submitter.get('name'), targets[0])
        else:
            targets = [submitter.get('email')]
            msg['To'] = Header('%s <%s>' % (submitter.get('name'), submitter.get('email')))

            ccaddrs = list()
            if tweaks.get('alwayscc'):
                ccaddrs += listify(tweaks['alwayscc'])
                targets += ccaddrs
            if tweaks.get('cclist'):
                ccaddrs.append(project.get('list_email'))
                targets.append(project.get('list_email'))
            if tweaks.get('ccall'):
                for addr in tos + ccs:
                    if addr not in targets:
                        targets.append(addr)
                        ccaddrs.append(addr)

            if 'alwaysbcc' in tweaks:
                targets += listify(tweaks['alwaysbcc'])

            if len(ccaddrs):
                msg['Cc'] = ', '.join(ccaddrs)

        if not NOMAIL:
            logger.debug('Message follows')
            logger.debug(msg.as_string())
            logger.info('Notifying %s', submitter.get('email'))

            smtp = smtplib.SMTP(MAILHOST)
            smtp.sendmail(tweaks['from'], targets, msg.as_bytes())
            smtp.close()
        else:
            logger.info('Would have sent the following:')
            logger.info('------------------------------')
            logger.info(msg.as_string())
            logger.info('------------------------------')


def housekeeping(pname: str) -> None:
    project, rm, pconfig = project_by_name(pname)
    if 'housekeeping' not in pconfig:
        return

    project_id = project['id']

    logger.info('Running housekeeping for %s', pname)
    hconfig = pconfig['housekeeping']
    cutoffdays = 90
    report = ''

    if 'autosupersede' in hconfig:
        logger.info('Getting series from %s/%s', rm.server, pname)
        try:
            cutoffdays = int(hconfig['autosupersede'])
        except ValueError:
            pass

        cutoffdate = datetime.datetime.now() - datetime.timedelta(days=cutoffdays)
        logger.debug('cutoffdate=%s', cutoffdate)
        series = dict()
        page = 0
        pagedata = list()
        lastpage = False
        while True:
            if not pagedata and not lastpage:
                page += 1
                logger.debug('  grabbing page %d', page)
                params = [
                    ('project', project_id),
                    ('order', '-date'),
                    ('page', page),
                    ('per_page', REST_PER_PAGE)
                ]
                # we do our own pagination
                pagedata = rm.get_series_list(params, unpaginated=False)

            if not pagedata:
                # Got them all?
                logger.debug('Finished processing all series')
                break

            entry = pagedata.pop()
            # Did we go too far back?
            s_date = entry.get('date')
            series_date = datetime.datetime.strptime(s_date, "%Y-%m-%dT%H:%M:%S")
            if series_date < cutoffdate:
                lastpage = True
                logger.debug('Went too far back, stopping at %s', series_date)
                continue

            s_id = entry.get('id')
            s_name = entry.get('name')
            if s_name is None:
                # Ignoring this one, because we must have a name
                continue

            # Remove any [foo] from the front, for best matching.
            # Usually, patchwork strips these, but not always.
            s_name = re.sub(r'^\[.*?]\s*', '', s_name)

            ver = entry.get('version')
            subm_id = entry.get('submitter').get('id')
            patches = list()
            for patch in entry.get('patches'):
                patches.append(patch.get('id'))

            if not patches:
                # Not sure how we can have a series without patches, but ok
                continue

            received_all = entry.get('received_all')
            if (subm_id, s_name) not in series:
                series[(subm_id, s_name)] = dict()

            series[(subm_id, s_name)][series_date] = {
                'id': id,
                'patches': patches,
                'complete': received_all,
                'date': s_date,
                'rev': ver,
            }
            logger.debug('Processed id=%s (%s)', s_id, s_name)

        for key, items in series.items():
            if len(items) < 2:
                # Not a redundant series
                continue

            subm_id, subject = key
            versions = list(items.keys())
            versions.sort()
            latest_version = versions.pop()
            logger.debug('%s: latest_version: %s', subject, items[latest_version]['date'])
            if not items[latest_version]['complete']:
                logger.debug('Skipping this series, because it is not complete')
                continue

            sreport = list()
            logger.info('Checking: [v%s] %s (%s)', items[latest_version]['rev'], subject,
                        items[latest_version]['date'])
            for v in versions:
                rev = items[v]['rev']
                s_date = items[v]['date']
                patch_id = items[v]['patches'][0]
                patch = rm.get_patch(patch_id)
                if not patch:
                    # Huh, what happened?
                    continue
                state = patch.get('state')
                if state != 'superseded':
                    logger.info('  Marking series as superseded: [v%s] %s (%s)', rev, subject, s_date)
                    sreport.append('  Superseding: [v%s] %s (%s):' % (rev, subject, s_date))
                    # Yes, we need to supersede these patches
                    for patch_id in items[v]['patches']:
                        logger.info('    Superseding patch: %d', patch_id)
                        patch = rm.get_patch(patch_id)
                        patch_title = patch.get('name')
                        current_state = patch.get('state')
                        if current_state == 'superseded':
                            logger.info('    Patch already set to superseded, skipping')
                            continue
                        sreport.append('    %s' % patch_title)
                        if not DRYRUN:
                            rm.update_patch(patch_id, state='superseded')
                        else:
                            logger.info('    Dryrun: Not actually setting state')

            if sreport:
                report += 'Latest series: [v%s] %s (%s)\n' % (items[latest_version]['rev'], subject,
                                                              items[latest_version]['date'])
                report += '\n'.join(sreport)
                report += '\n\n'

    if 'autoarchive' in hconfig:
        logger.info('Auto-archiving old patches in %s/%s', rm.server, pname)
        try:
            cutoffdays = int(hconfig['autoarchive'])
        except ValueError:
            pass

        cutoffdate = datetime.datetime.now() - datetime.timedelta(days=cutoffdays)
        logger.debug('cutoffdate=%s', cutoffdate)

        page = 0
        seen = set()
        pagedata = list()
        lastpage = False
        archived = 0
        while True:
            if not pagedata and not lastpage:
                if archived:
                    logger.info('Archived %d patches, grabbing next page', archived)
                params = [
                    ('project', project_id),
                    ('archived', 'false'),
                    ('state', 'new'),
                    ('order', 'date'),
                    ('per_page', REST_PER_PAGE)
                ]

                if DRYRUN:
                    # We don't need pagination if we're not in dryrun, because
                    # once we archive the patches, they don't show up in this
                    # query any longer.
                    page += 1
                    params.append(('page', page))

                # we do our own pagination
                pagedata = rm.get_patches_list(params, unpaginated=False)

            if not pagedata:
                logger.debug('Finished processing all patches')
                break

            entry = pagedata.pop()
            # Did we go too far forward?
            patch_date = datetime.datetime.strptime(entry.get('date'), "%Y-%m-%dT%H:%M:%S")
            if patch_date >= cutoffdate:
                # mark that we're on the last page
                lastpage = True
                continue

            patch_id = entry.get('id')
            if patch_id in seen:
                # If the archived setting isn't actually sticking on the server for
                # some reason, then we are in for an infinite loop. Recognize this
                # and quit when that happens.
                logger.info('Setting to archived is not working, exiting loop.')
                break

            seen.add(patch_id)
            archived += 1
            if not DRYRUN:
                rm.update_patch(patch_id, archived=True)
            else:
                logger.info('  Dryrun: Not actually archiving')

        if archived:
            logger.info('Archived %d total patches', archived)

        if not report:
            return

        if 'summaryto' not in pconfig:
            logger.info('Report follows')
            logger.info('------------------------------')
            logger.info(report)
            logger.info('------------------------------')
            logger.debug('summaryto not set, not sending report')
            return

        report += '\n-- \n' + CONFIG['templates']['signature']

        msg = MIMEText(report, _charset='utf-8')
        msg.replace_header('Content-Transfer-Encoding', '8bit')

        msg['Subject'] = 'Patchwork housekeeping for: %s' % pname
        msg['From'] = pconfig['from']
        msg['Message-Id'] = make_msgid('git-patchwork-housekeeping', domain=DOMAIN)
        msg['Date'] = formatdate(localtime=True)

        targets = listify(pconfig['summaryto'])
        msg['To'] = ', '.join(targets)
        if 'alwayscc' in pconfig:
            msg['Cc'] = ', '.join(listify(pconfig['alwayscc']))
            targets += listify(pconfig['alwayscc'])
        if 'alwaysbcc' in pconfig:
            targets += listify(pconfig['alwaysbcc'])

        if not NOMAIL:
            logger.debug('Message follows')
            logger.debug(msg.as_string())
            logger.info('Sending housekeeping summary to: %s', msg['To'])

            smtp = smtplib.SMTP(MAILHOST)
            smtp.sendmail(pconfig['from'], targets, msg.as_bytes())
            smtp.close()
        else:
            logger.info('Would have sent the following:')
            logger.info('------------------------------')
            logger.info(msg.as_string())
            logger.info('------------------------------')


def pwrun(repo: str, rsettings: Dict[str, Union[str, list, dict]]) -> None:
    global _rev_cache

    git_heads = git_get_repo_heads(repo, branch=rsettings.get('branch', '--heads'))
    if not git_heads:
        logger.info('Could not get the latest ref in %s', repo)
        sys.exit(1)

    dbpath = repo
    # If we're aimed at a worktree, move up from the ".git" file to
    # the worktree directory.
    if not os.path.isdir(dbpath):
        gitdir = open(dbpath).readline().strip()
        if not gitdir.startswith('gitdir: '):
            logger.info('Could not find git tree in %s', dbpath)
            sys.exit(1)
        gitdir = gitdir.split(' ', 1)[1]
        gitdir, worktree = os.path.split(gitdir)
        gitdir, category = os.path.split(gitdir)
        if category != "worktrees":
            logger.info('Could not find git worktree in %s', dbpath)
            sys.exit(1)
        # To store multiple pw.db files in a single .git directory,
        # add a suffix based on the repo treename.
        treename = rsettings.get('treename').replace('/', '_')
        dbpath = os.path.join(gitdir, f'pw-{treename}.db')
    else:
        dbpath = os.path.join(dbpath, 'pw.db')

    # Do we have a pw.db there yet?
    db_exists = os.path.isfile(dbpath)
    dbconn = sqlite3.connect(dbpath, sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
    c = dbconn.cursor()

    if not db_exists:
        db_init_pw_sqlite_db(c)
        initial_git_heads = git_get_repo_heads(repo, branch=rsettings.get('branch', '--heads'),
                                               ancestry=cmdargs.ancestors)
        db_save_repo_heads(c, initial_git_heads)
        # Exit early
        dbconn.commit()
        return

    db_heads = db_get_repo_heads(c)
    committers = rsettings.get('committers', list())

    newrevs = git_get_new_revs(repo, db_heads, git_heads, committers=committers, merges=True)
    if not newrevs:
        logger.debug('No new revs in %s', repo)
        return

    logger.info('Processing: %s', repo)

    count = 0
    for pname, psettings in rsettings['projects'].items():
        rpwhashes = dict()
        wantstates = list()
        have_prs = False
        for refname, revlines in newrevs.items():
            found = False
            for wanthead, hsettings in psettings.items():
                if refname.endswith(wanthead):
                    found = True
                    if 'fromstate' in hsettings:
                        wantstates += hsettings['fromstate']
                    break
            if not found:
                logger.debug('Skipping ref %s (not wanted)')
                continue

            rpwhashes[refname] = set()
            for rev, logline, committer in revlines:
                if logline.find('Merge') == 0 and logline.find('://') > 0:
                    have_prs = True
                    rpwhashes[refname].add((rev, logline, committer, None, None))
                    continue

                if rev not in _rev_cache:
                    info = git_get_rev_info(repo, rev)
                    pwhash = get_patchwork_hash(info)
                    if not pwhash:
                        # Theoretically, should never happen?
                        logger.debug('Skipping %s (no pwhash)', rev)
                        continue
                    msgid = None
                    lore_match = LORE_RE.search(info)
                    if lore_match:
                        msgid = lore_match.group(1)
                        logger.debug('Msgid for %s: %s', rev, msgid)
                    _rev_cache[rev] = (rev, logline, committer, pwhash, msgid)

                rpwhashes[refname].add(_rev_cache[rev])

        if not wantstates:
            wantstates = ['new', 'under-review']

        logger.debug('wantstates=%s', wantstates)

        logger.info(' project : %s', pname)
        project, rm, pconfig = project_by_name(pname)
        project_id = project['id']

        if have_prs:
            logger.info('  PR merge commit found, loading up pull requests')
            # Find all from states we're interested in
            prs = get_patchwork_pull_requests_by_project(rm, project_id, wantstates)
        else:
            prs = set()

        for refname, hashpairs in rpwhashes.items():
            logger.info('  Analyzing %d revisions in %s', len(hashpairs), refname)
            # Get our settings
            hsettings = None
            for wanthead, hsettings in psettings.items():
                if refname.endswith(wanthead):
                    break
            # Patchwork lowercases state name and replaces spaces with dashes
            to_state = hsettings['tostate'].lower().replace(' ', '-')
            fromstate = list()
            for fs in hsettings.get('fromstate', list()):
                fromstate.append(fs.lower().replace(' ', '-'))
            if not fromstate:
                fromstate = list(wantstates)

            # We create patch_id->rev mapping first
            revs = dict()
            committers = dict()
            for rev, logline, committer, pwhash, msgid in hashpairs:
                if have_prs and pwhash is None:
                    if logline.find(' of ') > 0:
                        matches = re.search(r'Merge\s\S+\s[\'\"](\S+)[\'\"]\sof\s(\w+://\S+)', logline)
                        if not matches:
                            continue
                        m_refname = matches.group(1)
                        m_host = matches.group(2)
                    elif logline.find('://') > 0:
                        matches = re.search(r'Merge\s(\w+://\S+)', logline)
                        if not matches:
                            continue
                        m_refname = 'master'
                        m_host = matches.group(1)
                    else:
                        continue

                    logger.debug('Looking for ref %s host %s', m_refname, m_host)

                    for pull_host, pull_refname, patch_id in prs:
                        if pull_host.find(m_host) > -1 and pull_refname.find(m_refname) > -1:
                            logger.info('  Found matching pull request in %s (id: %s)', logline, patch_id)
                            revs[patch_id] = rev
                            committers[patch_id] = committer
                            break
                    continue

                # Do we have a matching hash on the server?
                logger.info('  Matching by hash: %s (%s)', pwhash, logline)
                patch_ids = get_patchwork_patches_by_project_hash(rm, project_id, pwhash)
                if not patch_ids and msgid:
                    # Match by message-id, if we have it
                    logger.info('  Matching by msgid: %s (%s)', msgid, logline)
                    patch_ids = get_patchwork_patches_by_project_msgid(rm, project_id, msgid)
                if not patch_ids:
                    logger.info('    No match for: %s', logline)
                    continue

                for patch_id in patch_ids:
                    logger.info('   Matched: %s', patch_id)
                    pdata = rm.get_patch(patch_id)
                    if not pdata:
                        logger.info('   Ignoring due to REST error')
                        continue
                    if pdata.get('state') not in fromstate:
                        logger.info('   Ignoring due to state=%s', pdata.get('state'))
                        continue
                    revs[patch_id] = rev
                    committers[patch_id] = committer

            # Now we iterate through it
            updated_series = list()
            done_patches = set()
            for patch_id in list(revs.keys()):
                logger.info('   Processing: %s', patch_id)
                if patch_id in done_patches:
                    # we've already updated this series
                    logger.info('    Already applied as part of previous series')
                    continue
                pdata = rm.get_patch(patch_id)
                serieslist = pdata.get('series', None)
                if not serieslist:
                    # This is probably from the time before patchwork-2 migration.
                    # We'll just ignore those.
                    logger.info('    A patch without an associated series? Woah.')
                    continue

                for series in serieslist:
                    series_id = series.get('id')
                    sdata = rm.get_series(series_id)
                    update_queue = list()
                    for spatch in sdata.get('patches'):
                        spatch_id = spatch.get('id')

                        if spatch_id in revs:
                            rev = revs[spatch_id]
                            update_queue.append((spatch.get('name'), spatch_id, to_state, rev))

                    if update_queue:
                        logger.info('Marking series "%s": %s', to_state, sdata.get('name'))
                        updated_series.append(sdata)
                        for sname, spatch_id, to_state, rev in update_queue:
                            count += 1
                            done_patches.update([spatch_id])
                            if not DRYRUN:
                                logger.info('  Updating: %s', sname)
                                rm.update_patch(spatch_id, state=to_state, commit_ref=rev)
                            else:
                                logger.info('  Updating (DRYRUN): %s', sname)

            if len(updated_series) and hsettings.get('send_summary', False):
                send_summary(updated_series, committers, to_state, refname, revs, pname, rsettings, hsettings)
            if len(updated_series) and hsettings.get('notify_submitter', False):
                notify_submitters(updated_series, committers, refname, revs, pname, rsettings, hsettings)

        if count:
            logger.info('Updated %d patches on %s', count, rm.server)
        else:
            logger.info('No patches updated on %s', rm.server)

    if not DRYRUN:
        db_save_repo_heads(c, git_heads)
        dbconn.commit()


def check_repos() -> None:
    # Use a global lock to make sure only a single process is running
    try:
        lockfh = open(os.path.join(CACHEDIR, 'patchwork-bot.global.lock'), 'w')
        lockf(lockfh, LOCK_EX | LOCK_NB)
    except IOError:
        logger.info('Could not obtain an exclusive lock, assuming another process is running.')
        sys.exit(0)

    for repo in CONFIG['repos']:
        fullpath = os.path.join(cmdargs.reposdir.rstrip('/'), repo.lstrip('/'))
        if not os.path.exists(fullpath):
            logger.info('Repository not found: %s', repo)
            continue
        settings = CONFIG['repos'][repo]
        if not os.path.isdir(fullpath) and not settings.get('branch'):
            logger.info('Worktree must specify "branch" setting: %s', repo)
            continue
        pwrun(fullpath, settings)


def pwhash_differ() -> None:
    diff = sys.stdin.read()
    inhash = get_patchwork_hash(diff)
    logger.info('stdin hash: %s', inhash)
    check_patch_id = cmdargs.pwhash
    for pw in CONFIG['patchworks']:
        logger.info('Patchwork: %s', pw)
        for pname, psettings in CONFIG['patchworks'][pw]['projects'].items():
            project, rm, pconfig = project_by_name(pname)
            patch = rm.get_patch(check_patch_id)
            if patch.get('hash') != inhash:
                logger.info('--- patchwork diff ---')
                logger.info(patch.get('diff'))
                logger.info('--- hash: %s ---', patch.get('hash'))
                sys.exit(1)
    logger.info('No mismatches found')
    sys.exit(0)


if __name__ == '__main__':
    # noinspection PyTypeChecker
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    parser.add_argument('-c', '--cfgfile', required=True,
                        help='Config file with repository and project data.')
    parser.add_argument('-r', '--reposdir', default=None,
                        help='Directory with repositories to process')
    parser.add_argument('-l', '--logfile', default=None,
                        help='Log file for messages during quiet operation')
    parser.add_argument('-m', '--mailhost', default='localhost',
                        help='Mailhost to use when sending mail')
    parser.add_argument('-d', '--dry-run', dest='dryrun', action='store_true', default=False,
                        help='Do not mail or store anything, just do a dry run.')
    parser.add_argument('-n', '--no-mail', dest='nomail', action='store_true', default=False,
                        help='Do not mail anything, but store database entries.')
    parser.add_argument('-q', '--quiet', action='store_true', default=False,
                        help='Only output errors to the stdout')
    parser.add_argument('-v', '--verbose', action='store_true', default=False,
                        help='Be more verbose in logging output')
    parser.add_argument('-k', '--housekeeping', action='store_true', default=False,
                        help='Perform a housekeeping run (supersede, archive)')
    parser.add_argument('--cachedir', default=None,
                        help='Cache directory to use instead of ~/.cache/git-patchwork-bot')
    parser.add_argument('--domain', default=None,
                        help='Domain to use when creating message-ids')
    parser.add_argument('--ancestors', default=None,
                        help='During initial database creation, consider this many ancestor commits as fresh')
    parser.add_argument('--pwhash', default=None, type=int, metavar='PATCH-ID',
                        help='Debug pwhash mismatches. Compare patchwork hash of diff from stdin to patch id')
    parser.add_argument('--tokens-file', default=None,
                        help='Separate configuration file containing just API tokens')

    cmdargs = parser.parse_args()

    logger.setLevel(logging.DEBUG)

    if cmdargs.logfile:
        ch = logging.FileHandler(cmdargs.logfile)
        formatter = logging.Formatter(
            '[%(asctime)s] %(message)s')
        ch.setFormatter(formatter)

        if cmdargs.verbose:
            ch.setLevel(logging.DEBUG)
        else:
            ch.setLevel(logging.INFO)
        logger.addHandler(ch)

    ch = logging.StreamHandler()
    formatter = logging.Formatter('%(message)s')
    ch.setFormatter(formatter)

    if cmdargs.quiet:
        ch.setLevel(logging.CRITICAL)
    elif cmdargs.verbose:
        ch.setLevel(logging.DEBUG)
    else:
        ch.setLevel(logging.INFO)

    logger.addHandler(ch)
    if cmdargs.nomail or cmdargs.dryrun:
        logger.info('NOMAIL: ON')
        NOMAIL = True
    if cmdargs.dryrun:
        logger.info('DRYRUN: ON')
        DRYRUN = True
    if cmdargs.cachedir:
        CACHEDIR = cmdargs.cachedir
    if cmdargs.domain:
        DOMAIN = cmdargs.domain
    MAILHOST = cmdargs.mailhost

    with open(cmdargs.cfgfile, 'r') as fh:
        cfgyaml = fh.read()
    CONFIG = ruamel.yaml.safe_load(cfgyaml)

    if cmdargs.tokens_file:
        with open(cmdargs.tokens_file, 'r') as fh:
            tkyaml = fh.read()
        tks = ruamel.yaml.safe_load(tkyaml)
        for _pserver, _sconfig in tks['patchworks'].items():
            if _pserver in CONFIG['patchworks']:
                logger.debug('Taking apitoken info for %s from %s', _pserver, cmdargs.tokens_file)
                CONFIG['patchworks'][_pserver]['apitoken'] = _sconfig.get('apitoken')

    if not os.path.isdir(CACHEDIR):
        os.makedirs(CACHEDIR, exist_ok=True)

    if cmdargs.pwhash:
        pwhash_differ()
        sys.exit(0)

    if cmdargs.housekeeping:
        for _pserver, _sconfig in CONFIG['patchworks'].items():
            for _pname in _sconfig['projects']:
                housekeeping(_pname)
    else:
        if not cmdargs.reposdir:
            logger.critical('-r is required for this mode')
            sys.exit(1)
        check_repos()
