#!/usr/bin/python3

import psycopg2
from importlib import machinery, util


def load_config(name, filename):
    """
    DUPLICATE CODE. This function is also defined in perfact-autocommit-etc.
    Leave duplicate code here because the overhead for a python module is too
    high.
    Read a config from a py file with the given filename.
    Return config as a dictionary.
    """
    # Read config from file. This code is copied from python-perfact.generic
    loader = machinery.SourceFileLoader(name, filename)
    spec = util.spec_from_loader(loader.name, loader)
    mod = util.module_from_spec(spec)
    loader.exec_module(mod)

    return {
        name: getattr(mod, name)
        for name in dir(mod)
        if not name.startswith('_')
    }


filename = '/etc/perfact/systemtools/compare-pgextension-config.py'
name = 'config'

config = load_config(name, filename)

databases = config.get('databases')
dbhost = config.get('dbhost')
dbport = config.get('dbport')

query = '''select name, default_version, installed_version
           from pg_available_extensions
           where default_version <> installed_version;
'''


for database in databases.keys():
    print(f'Checking for different extensions on database "{database}"')
    dbconn_string = (f'host={dbhost} port=5432 dbname={database} '
                     f'user={databases[database]} connect_timeout=5')
    dbconn = psycopg2.connect(dbconn_string)
    with dbconn.cursor() as cur:
        cur.execute(query)
        rows = cur.fetchall()
        if len(rows) > 0:
            for row in rows:
                print(f'Extension "{row[0]}" has to be updated! '
                      f'Old version: {row[1]} | '
                      f'Available version: {row[2]}\n'
                      f'Update extension with: psql -d {database} '
                      f'-U {databases[database]} '
                      f'-c "alter extension {row[0]} update;"\n'
                      )
        else:
            print('No differences found')
        cur.close()
        dbconn.close()
    print("\n")
