#!/usr/bin/env python

INVENTORY = {}


def goodbye():
    print(json.dumps(INVENTORY))
    sys.exit(0)


if '__main__' == __name__:
    import os
    import re
    import sys
    import glob
    import json
    import argparse
    import variables

    EXTENSION = '.private.key'
    MATRICES_FILE = '%s/.hosts.json' % variables.dirs['lib']

    parser = argparse.ArgumentParser()
    group = parser.add_mutually_exclusive_group(required=True)

    group.add_argument('--list', action='store_true')
    group.add_argument('--host', action='store')

    arguments = parser.parse_args()
    matrices = json.load(open(MATRICES_FILE)) if os.path.isfile(MATRICES_FILE) else {}

    # Walk through the global and project credentials.
    for directory in [variables.dirs['cikit'], variables.dirs['self']]:
        credentials_dir = '%s/credentials' % directory

        # Can't move on without the necessary directory.
        if not os.path.isdir(credentials_dir):
            continue

        for matrix_name in os.listdir(credentials_dir):
            matrix_credentials_dir = '%s/%s' % (credentials_dir, matrix_name)
            matrix_hostname_file = '%s/.hostname' % matrix_credentials_dir

            # When the matrix's host is explicitly defined we're gonna use it and dump
            # its hostname to the file. It's ok that we will create/overwrite the value
            # in a global storage (second iteration of the parent loop).
            if matrix_name in matrices:
                matrix_hostname = matrices[matrix_name]['hosts'][0]

                with open(matrix_hostname_file, 'w') as matrix_hostname_file:
                    matrix_hostname_file.write(matrix_hostname)
                    matrix_hostname_file.close()
            # The matrix's host is not defined on someone's computer. It's not required,
            # so we're just gonna read its hostname from the file.
            elif os.path.isfile(matrix_hostname_file):
                with open(matrix_hostname_file, 'r') as matrix_hostname_file:
                    matrix_hostname = matrix_hostname_file.readline().strip()
                    matrix_hostname_file.close()
            # The matrix's hostname cannot be determined nor by the stored hostname
            # neither by the explicit definition of itself.
            else:
                continue

            if os.path.isdir(matrix_credentials_dir):
                for private_key_file in glob.glob('%s/*/*%s' % (matrix_credentials_dir, EXTENSION)):
                    droplet_name = os.path.basename(private_key_file).rstrip(EXTENSION)

                    INVENTORY['%s.%s' % (matrix_name, droplet_name)] = {
                        'hosts': ['%s.%s' % (droplet_name, matrix_hostname)],
                        'vars': {
                            'ansible_user': 'root',
                            'ansible_port': '22%s' % re.sub('[^\d+]', '', droplet_name),
                            'ansible_ssh_private_key_file': private_key_file,
                        },
                    }

    # Append available matrices to the inventory.
    INVENTORY.update(matrices)

    if arguments.host:
        # A specific host has been requested. Limit the results, to
        # print only information about it.
        if arguments.host in INVENTORY:
            INVENTORY = {
                arguments.host: INVENTORY[arguments.host],
            }
        # A specific host has been requested but wasn't found in a
        # list. Nothing to print.
        else:
            INVENTORY = {}

    goodbye()
