import pymongo
import mysql



'''
This module performs the subscriber information processing
1. Gets the existing subscriber list from MongoDB
2. Gets the live subscriber list from the MySQL DB
3. Compares the two lists and returns ONLY anything that has changed
4. Updates any changes to the live subscriber list collection
5. Inserts changes in to the tetra_subscriber_changes collection for change history
'''



def getExistingSubscribers(DB: pymongo.MongoClient) -> list:
    '''
    Gets the existing subscriber list for comparision
    '''
    subscribers = DB['tetra_subscribers'].find()
    subscribers = list(subscribers)
    return(subscribers)


def getCurrentSubscribers(CURSOR: mysql.connector):
    '''
    Retrieves the current subscriber list.
    '''
    # Execute MySQL query
    CURSOR.execute("SELECT \
        SSI, \
        Description, \
        SsiKind, \
        ProfileId, \
        Timestamp \
        FROM `subscriber`;"
    )
    subscribers = CURSOR.fetchall()

    new_subs = []

    for subscriber in subscribers:
        if subscriber[2] == 1:
            s_type = 'Subscriber'
        elif subscriber[2] == 2:
            s_type = 'Group'
        elif subscriber[2] == 5:
            s_type = 'Application'
        elif subscriber[2] == 8:
            s_type = 'Terminal'
    
        new_sub = {
            'ssi' : subscriber[0],
            'description' : subscriber[1],
            'type' : s_type,
            'profile' : subscriber[3],
            'timestamp' : subscriber[4]
        }

        new_subs.append(new_sub)

    return(new_subs)


def getDifference(
        previous: list,
        latest: list
    ) -> list:
    '''
    Compares two lists of dictionaries and returns a list of dictionaries that have changed
    Absolute wiardry 
    '''

    changed = []

    # Iterate over the latest subscriber list
    for sub in latest:
        # Check if there is an issi match between the new and old subscriber list
        match = next((item for item in previous if item["ssi"] == sub['ssi']), None)
        # If there is a match...
        if match:
            # Create a set of the values
            previous_match = set(match.items())
            latest_match = set(sub.items())
            # Remove any values that are the same
            difference = latest_match - previous_match
            # Convert back to a dictionary
            difference = dict(difference)
            # If there is a difference
            # (No difference does nothing)
            if difference:
                try:
                    # Try if there is a comment (blank most of the time)
                    sub['comment'] = difference['comment']
                except KeyError:
                    pass
                # Append the subscriber to the final list
                changed.append(sub)
        else:
            # No match = new subscriber
            # Append to the list
            changed.append(sub)

    return(changed)


def updateDB(
        DB: pymongo.MongoClient,
        data: list
    ) -> None:
    '''
    Updates MongoDB
    '''
    print(len(data))
    print(data[0])

    for sub in data:
        # Tecnically should only update differences or new subscribers if any
        DB['tetra_subscribers'].find_one_and_update(
            {
                'ssi' : sub['ssi']
            },
            {
                '$set' : sub
            },
            upsert=True
        )

    # Log the subscriber changes
    DB['tetra_subscriber_changes'].insert_many(data)
    

def tetraSubscribers(
        CURSOR: mysql,
        DB: pymongo.MongoClient
    ) -> None:
    '''
    Compares the previous and latest subscriber lists and logs any changes
    '''
    # Get the existing subscriber list
    previous = getExistingSubscribers(DB)
    # Get the new subscriber list
    latest = getCurrentSubscribers(CURSOR)
    # Compare and return the difference
    difference = getDifference(previous, latest)
    # Only update the MongoDB collection if there are any differenes
    if len(difference) > 0:
        updateDB(DB, difference)
    print(f"Updated {len(difference)} changed subscribers")


def msLocation(
        CURSOR: mysql,
        DB: pymongo.MongoClient
    ) -> None:
    ''' 
    Get current node a subscriber is associated to
    '''
    # Execute MySQL query
    CURSOR.execute("SELECT \
        Ssi, \
        NodeDescr \
        FROM `mslocation`"
    )
    myresult = CURSOR.fetchall()
    # Iterate over the subscribers
    for subscriber in myresult:
        # Update the subscriber collection with the currently connected node
        node = subscriber[1]        
        DB['tetra_subscribers'].find_one_and_update(
            {
                'ssi' : subscriber[0],
            },
            {
                '$set': {
                    'node' : node
                }
            },
            upsert=True
        )
import pymongo
import mysql



'''
This module performs the subscriber information processing
1. Gets the existing subscriber list from MongoDB
2. Gets the live subscriber list from the MySQL DB
3. Compares the two lists and returns ONLY anything that has changed
4. Updates any changes to the live subscriber list collection
5. Inserts changes in to the tetra_subscriber_changes collection for change history
'''



def getExistingSubscribers(DB: pymongo.MongoClient) -> list:
    '''
    Gets the existing subscriber list for comparision
    '''
    subscribers = DB['tetra_subscribers'].find()
    subscribers = list(subscribers)
    return(subscribers)


def getCurrentSubscribers(CURSOR: mysql.connector):
    '''
    Retrieves the current subscriber list.
    '''
    # Execute MySQL query
    CURSOR.execute("SELECT \
        SSI, \
        Description, \
        SsiKind, \
        ProfileId, \
        Timestamp \
        FROM `subscriber`;"
    )
    subscribers = CURSOR.fetchall()

    new_subs = []

    for subscriber in subscribers:
        if subscriber[2] == 1:
            s_type = 'Subscriber'
        elif subscriber[2] == 2:
            s_type = 'Group'
        elif subscriber[2] == 5:
            s_type = 'Application'
        elif subscriber[2] == 8:
            s_type = 'Terminal'
    
        new_sub = {
            'ssi' : subscriber[0],
            'description' : subscriber[1],
            'type' : s_type,
            'profile' : subscriber[3],
            'timestamp' : subscriber[4]
        }

        new_subs.append(new_sub)

    return(new_subs)


def getDifference(
        previous: list,
        latest: list
    ) -> list:
    '''
    Compares two lists of dictionaries and returns a list of dictionaries that have changed
    Absolute wiardry 
    '''

    changed = []

    # Iterate over the latest subscriber list
    for sub in latest:
        # Check if there is an issi match between the new and old subscriber list
        match = next((item for item in previous if item["ssi"] == sub['ssi']), None)
        # If there is a match...
        if match:
            # Create a set of the values
            previous_match = set(match.items())
            latest_match = set(sub.items())
            # Remove any values that are the same
            difference = latest_match - previous_match
            # Convert back to a dictionary
            difference = dict(difference)
            # If there is a difference
            # (No difference does nothing)
            if difference:
                try:
                    # Try if there is a comment (blank most of the time)
                    sub['comment'] = difference['comment']
                except KeyError:
                    pass
                # Append the subscriber to the final list
                changed.append(sub)
        else:
            # No match = new subscriber
            # Append to the list
            changed.append(sub)

    return(changed)


def updateDB(
        DB: pymongo.MongoClient,
        data: list
    ) -> None:
    '''
    Updates MongoDB
    '''
    print(len(data))
    print(data[0])

    for sub in data:
        # Tecnically should only update differences or new subscribers if any
        DB['tetra_subscribers'].find_one_and_update(
            {
                'ssi' : sub['ssi']
            },
            {
                '$set' : sub
            },
            upsert=True
        )

    # Log the subscriber changes
    DB['tetra_subscriber_changes'].insert_many(data)
    

def tetraSubscribers(
        CURSOR: mysql,
        DB: pymongo.MongoClient
    ) -> None:
    '''
    Compares the previous and latest subscriber lists and logs any changes
    '''
    # Get the existing subscriber list
    previous = getExistingSubscribers(DB)
    # Get the new subscriber list
    latest = getCurrentSubscribers(CURSOR)
    # Compare and return the difference
    difference = getDifference(previous, latest)
    # Only update the MongoDB collection if there are any differenes
    if len(difference) > 0:
        updateDB(DB, difference)
    print(f"Updated {len(difference)} changed subscribers")


def msLocation(
        CURSOR: mysql,
        DB: pymongo.MongoClient
    ) -> None:
    ''' 
    Get current node a subscriber is associated to
    '''
    # Execute MySQL query
    CURSOR.execute("SELECT \
        Ssi, \
        NodeDescr \
        FROM `mslocation`"
    )
    myresult = CURSOR.fetchall()
    # Iterate over the subscribers
    for subscriber in myresult:
        # Update the subscriber collection with the currently connected node
        node = subscriber[1]        
        DB['tetra_subscribers'].find_one_and_update(
            {
                'ssi' : subscriber[0],
            },
            {
                '$set': {
                    'node' : node
                }
            },
            upsert=True
        )
This module performs the subscriber information processing 1. Gets the existing subscriber list from MongoDB 2. Gets the live subscriber list from the MySQL DB 3. Compares the two lists and returns ONLY anything that has changed 4. Updates any changes to the live subscriber list collection 5. Inserts changes in to the tetra_subscriber_changes collection for change history Gets the existing subscriber list for comparision Retrieves the current subscriber list. # Execute MySQL query Compares two lists of dictionaries and returns a list of dictionaries that have changed     Absolute wiardry # Iterate over the latest subscriber list # Check if there is an issi match between the new and old subscriber list # If there is a match... # Create a set of the values # Remove any values that are the same # Convert back to a dictionary # If there is a difference # (No difference does nothing) # Try if there is a comment (blank most of the time) # Append the subscriber to the final list # No match = new subscriber # Append to the list Updates MongoDB # Tecnically should only update differences or new subscribers if any # Log the subscriber changes Compares the previous and latest subscriber lists and logs any changes # Get the existing subscriber list # Get the new subscriber list # Compare and return the difference # Only update the MongoDB collection if there are any differenes Get current node a subscriber is associated to # Execute MySQL query # Iterate over the subscribers # Update the subscriber collection with the currently connected node