#!/usr/bin/env python3

# SPDX-FileCopyrightText: 2009 Fermi Research Alliance, LLC
# SPDX-License-Identifier: Apache-2.0

# TODO: This can be removed, there are no more Factories older than v3.5
"""Check if the Factory setup is 3.5 ready.

This script verifies that the client and proxy directories in the Factory
configuration are owned by the current user, that the jobs are running with the
same owner, and that no Globus GT2 entries are enabled in the configuration.

This is needed for the transition from multi-users Factory to a Factory running
under a single user.
"""

import os
import sys
import getpass

import htcondor

from glideinwms.creation.lib import factoryXmlConfig


VERBOSE = False


def log(*args):
    """Print success messages when verbose mode is enabled (no --quiet option).

    Args:
        *args: Variable length argument list to be printed.
    """
    if VERBOSE:
        print(*args)


def main():
    """Check if the factory configuration is 3.5 ready.

    Loads the configuration file, verifies that the client and proxy directories
    are owned by the current user, checks that all jobs are owned by the current user,
    and ensures that no GT2 entries are enabled.

    Returns:
        int: 0 if all checks pass;
             1 if a directory ownership mismatch is found;
             2 if jobs are owned by multiple users;
             3 if jobs are not owned by the current user;
             4 if any GT2 entries are enabled.
    """
    conf_file = '/etc/gwms-factory/glideinWMS.xml'
    log('Loading configuration file %s' % conf_file)
    conf = factoryXmlConfig.parse(conf_file)
    uid = os.getuid()
    user = getpass.getuser()

    # pylint: disable=maybe-no-member
    dir_dicts = [conf.get_client_log_dirs(), conf.get_client_proxy_dirs()]

    for client_dir_dict in dir_dicts:
        for _, fe_client_dir in client_dir_dict.items():
            cid = os.stat(fe_client_dir).st_uid
            if cid != uid:
                print(("Directory %s is owned by user with id %s, while the user running this "
                       "process is %s") % (fe_client_dir, cid, uid))
                return 1
    log('Checked ownership (%s) of client and proxies directories. Passed' % user)

    # Query all the schedds for job owners
    queries = []
    coll_query = htcondor.Collector().locateAll(htcondor.DaemonTypes.Schedd)
    for schedd_ad in coll_query:
        schedd_obj = htcondor.Schedd(schedd_ad)
        queries.append(schedd_obj.xquery(projection=["Owner"]))

    users = set()
    i = 0
    for query in htcondor.poll(queries):
        try:
            users.add(query.__next__()["Owner"])
            i += 1
        except StopIteration:
            pass
    log("Checked Owner of %s jobs" % i)
    if i == 0:
        log("No jobs running. Passed")
    elif len(users) > 1:
        print("Found that jobs Owner are: " + ", ".join(users))
        print("All the jobs Owner should be %s instead" % user)
        return 2
    else:
        jobuser = users.pop()
        if user != jobuser:
            print("All the jobs have owner %s, while the user running this process is %s" %
                  (jobuser, user))
            return 3
        else:
            log("All jobs have the %s user. Passed" % user)

    # checking entries
    entry_dicts = conf.get_entries()
    gt2_entries = []
    for entry_dict in entry_dicts:
        if entry_dict['enabled'] == u'True' and entry_dict.get('gridtype', 'NONE') == u'gt2':
            gt2_entries.append(entry_dict['name'])
    if gt2_entries:
        print("Entries %s are enabled and use unsupported Globus GT2. Should be disabled." %
              (', '.join(gt2_entries),))
        return 4
    else:
        log("No Globus GT2 entries. Passed.")

    return 0


if __name__ == '__main__':
    if len(sys.argv) > 1 and (sys.argv[1] == '--verbose' or sys.argv[1] == '-v'):
        VERBOSE = True
    RET = main()  # capital letters used because pylint considers this a constant
    if RET != 0:
        print("Please, make sure to run the fact_chown script. More details at "
              "https://glideinwms.fnal.gov/doc.v3_5_1/factory/configuration.html#single_user")
    sys.exit(RET)
