#!/usr/bin/python3

import time
import argparse
import subprocess as sp

repo = '/opt/perfact/dbutils-zoperepo'


def reset_db():
    """
    Fetch the database from ema-validation and reset our database to its state.
    """
    # Disable all sensitive services first
    services = [
        'perfact-measure',
        'monit',
        'perfact-assignd',
        'perfact-dbcached',
    ]
    try:
        sp.run(['sudo', 'systemctl', 'stop'] + services, check=True)
        sp.run(
            [
                '/opt/perfact/migration/bin/migrate-db',
                'fetch', 'restore', 'upgrade', 'rename', 'zope-exec',
                'fetch-file-repo', 'move-into-place',
            ],
            check=True,
        )
        sp.run(['sudo', 'pg_dropcluster', '15', 'template'], check=True)
        sp.run(['sudo', 'rm', '-rf', '/etc/postgresql/15/template'],
               check=True)
    finally:
        sp.run(['sudo', 'systemctl', 'start'] + services, check=True)


def sync_repo():
    """
    Sync the Zope repository to the state of the master branch on
    git.perfact.de
    """
    sp.run(
        'git fetch -p origin'.split(),
        cwd=repo,
        check=True,
    )
    changes = sp.check_output(['git', 'status', '--porcelain'], cwd=repo)
    if changes.strip():
        sp.run('git add .'.split(), cwd=repo, check=True)
        sp.run(
            ['git', 'commit', '-m', 'perfact-sync-repo revert'],
            cwd=repo,
        )

    commit_ids = [
        sp.check_output(['git', 'rev-parse', rev], cwd=repo).strip()
        for rev in ['master', 'origin/master']
    ]

    if commit_ids[0] != commit_ids[1]:
        sp.run(
            'zodbsync reset origin/master'.split(),
            check=True,
        )


if __name__ == '__main__':
    with open('/etc/pfsystemname') as f:
        pfsystemname = f.read().strip()

    for prefix in ['ema-devel-', 'ema-validation-', 'ema-bugfixes-']:
        if pfsystemname.startswith(prefix):
            break
    else:
        raise ValueError(
            "This script must only be executed on"
            " ema-devel/validation/bugfixes"
        )

    parser = argparse.ArgumentParser(
        description="""
            Helper to reset the Zope repository and possibly the database of a
            system.
        """
    )
    parser.add_argument(
        "--loop", action="store_true",
        help="Keep running and execute once a minute"
    )

    parser.add_argument(
        "--include-db", action="store_true",
        help="Also fetch and reset database from source-system"
    )
    args = parser.parse_args()

    while True:
        if args.include_db:
            reset_db()
        sync_repo()

        if not args.loop:
            break
        time.sleep(60)
