#!/usr/bin/env python
# TODO: Create release updated table
# TODO: Can I remove the select in the instance loop? Load the instance table into a dict and test against that??? Line 143
# FIXME: Handle release merges Instance ID: 189217788

from __future__ import print_function
from datetime import datetime

import discogs_client
# import os
import pprint
import sys
# import traceback
import dbqueries as dbq
import dblog
import hashlib
from utilities import *

# Import config
from config import *

pp = pprint.PrettyPrinter(indent=4)


# Discogs API setup
discogs = discogs_client.Client(UserAgent, user_token=AuthToken)
user = discogs.identity()

process_name = "migrate discogs"

def migrate_discogs():
    """
    This is the main function for getting information from discogs into our local migration tables
    """
    
    # Check for the right DB schema version. We may want to do automatic DB updates somehow
    check_db_version()
    
    # Get the instance run_id, currently only use this for marking the end
    run_id = dblog.startup(process_name)
    
    # Custom field name and ID, populate database
    getcustomfields()

    # Update Instance Table
    discogsImport(discogs_folder)
    
    # Process sales channels
    stores = get_stores()
    saleschannels("new", stores)
    saleschannels("update", stores)

    # Populate release information
    discogs_new_releases()
    # TODO:    discogs_update_releases()

    # TODO: get labels / flag for create 

    """ TODO: Remove this section
    Attribute terms can be created on the fly and will match existing
    
    # TODO: get genres / flag for create attribute
    getattribs("genres")
    
    # TODO: getstyles()
    getattribs("styles")
    """
    
    # TODO: get artists / flag for create
    # TODO: get decades? / flag for create
    # TODO: populate catagories table
    # TODO: Valuations from discogs
    # TODO: releases updated
    # TODO: Move sold to zz Sold folder
    # TODO: Get images
    dblog.finished(run_id)
    
def get_stores():
    stores = {}
    store_fields = dbq.exec_db_query_dict(dbq.get_store_fields,  qty="all")
    for idx in range(len(store_fields)):
        stores[store_fields[idx]['field_id']] = store_fields[idx]['field_name']
    return stores

def saleschannels(type,  stores):
    """
    Type is either new or update
    """
    if type == "new":
        query = dbq.insert_sales_channels
        get_query = dbq.get_new_instance_notes
        date_field = "insert_date"
    elif type == "update":
        query = dbq.update_sales_channels
        get_query = dbq.get_updated_instance_notes
        date_field = "update_date"

    db_instance_notes = dbq.exec_db_query_dict(get_query,  qty="all")
    for inst_idx in range(len(db_instance_notes)):
        channels = {}
        notes = list(eval(db_instance_notes[inst_idx]['notes']))
        for notes_idx in range(len(notes)):
            store = dict_switcher(notes[notes_idx]['field_id'],  stores)
            if store != None:
                notes[notes_idx]['value']
                channels[store] = notes[notes_idx]['value']

        query_data = {'instance_id': db_instance_notes[inst_idx]['instance_id'],
                                'sales_channels': str(channels),
                                date_field: datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        dbq.exec_db_query(query, query_data, query_type='insert')

# Hash instance notes
def hashNotes(instance_notes):
    """
    Sums the concatenated notes field.
    This provides a check for updates
    """
    try:
        notes_chksum = hashlib.md5()
        notes_chksum.update(str(instance_notes).encode())
    except:
        pass
    else:
        return notes_chksum
    finally:
        del notes_chksum


# TODO: Fix how artists and labels are stored.
def discogs_new_releases():
    """
    Get/Update release table,
    """
    import_new_releases = dbq.exec_db_query(dbq.get_new_release_list, qty='all')
    import_new_releases = [i[0] for i in import_new_releases]

    for index in range(len(import_new_releases)):
        release = discogs.release(import_new_releases[index])
        release_data = {'release_id': release.id,
                                    'title': release.title,
                                    'artists': str(release.artists),
                                    'labels':str( release.labels),
                                    'styles': str(release.styles),
                                    'genres': str(release.genres),
                                    'url': str(release.url),
                                    'discogs_date_added': release.date_added, 
                                    'discogs_date_changed': release.date_changed, 
                                    'insert_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        
        dbq.exec_db_query(dbq.import_new_release,  release_data, query_type='insert')

        
def discogs_update_releases():
    # FIXME: This is a copy on the new function, should probably combine them
    """
    Get/Update release table
    """
    import_new_releases = dbq.exec_db_query(dbq.get_new_release_list, qty='all')
    import_new_releases = [i[0] for i in import_new_releases]

    for index in range(len(import_new_releases)):
        release = discogs.release(import_new_releases[index])
        release_data = {'release_id': release.id,
                                    'title': release.title,
                                    'artists': str(release.artists),
                                    'labels':str( release.labels),
                                    'styles': str(release.styles),
                                    'genres': str(release.genres),
                                    'url': str(release.url),
                                    'discogs_date_added': release.date_added, 
                                    'discogs_date_changed': release.date_changed, 
                                    'insert_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        
        dbq.exec_db_query(dbq.import_update_release,  release_data, query_type='insert')

# Get Discogs instance info
def discogsImport (discogs_folder):
    """
    Imports discogs collections to table
    """

    # Set collection 
    collection = user.collection_folders

    # Populate import table
    for album in collection[discogs_folder].releases:
        query = None

        # Concatenate notes
        hashing_note = None
        if album.notes != None:
            for idx in range(len(album.notes)):
                hashing_note = str(hashing_note) + str(album.notes[idx]['field_id']) + str(album.notes[idx]['value'])

        # Hash the notes
        notes_chksum = hashNotes(hashing_note)

        #  Query instance table for instance
        db_instance = dbq.exec_db_query_dict(dbq.get_instance_info, album.instance_id)

        # New items
        if db_instance == None:

            # Build insert data
            query_data = {'instance_id': album.instance_id,
                                    'rating': album.rating,
                                    'title': album.release.title,
                                    'folder_id': album.folder_id,
                                    'discogs_date_added':  album.date_added,
                                    'notes': str(album.notes),
                                    'notes_chksum': notes_chksum.hexdigest(),
                                    'release_id': album.id, 
                                    'insert_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
            query = dbq.add_instance
            dbq.exec_db_query(query, query_data, query_type='insert')

        # Test for existing and changed
        elif db_instance['instance_id'] == album.instance_id and \
              (db_instance['notes_chksum'] != notes_chksum.hexdigest() or 
              db_instance['folder_id'] != album.folder_id or 
              db_instance['release_id'] != album.id ):

            # Update notes if hash is different
            if db_instance['notes_chksum'] != notes_chksum.hexdigest():
                query_data = {'notes': str(album.notes),
                                         'notes_chksum': notes_chksum.hexdigest(),
                                         'update_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),  
                                         'instance_id': album.instance_id, 
                                         'release_id':  album.id}
                query = dbq.update_instance_notes_chksum
                dbq.exec_db_query(query, query_data, query_type='insert')

            # Update folder id
            if db_instance['folder_id'] != album.folder_id:
                query_data = {'folder_id': album.folder_id,
                                         'update_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),  
                                         'instance_id': album.instance_id}
                query = dbq.update_instance_folder_id
                dbq.exec_db_query(query, query_data, query_type='insert')
                
            if db_instance['release_id'] != album.id:
                query_data = {'release_id':  album.id, 
                                        'instance_id': album.instance_id}
                query = dbq.update_instance_release_id
                dbq.exec_db_query(query, query_data, query_type='insert')
                

#FIXME: remove
#        # Execute queries
#        if query != None:
#            dbq.exec_db_query(query, query_data, query_type='insert')


# Query DB for instance data
def getInstanceData(instance_id):
    dbcursor_dict.execute(dbq.get_instance_info,  (instance_id,))
    instance_data = dbcursor_dict.fetchone()
    return instance_data


# TODO: This is not working for labels and artists. The formating is wrong on the db data
def getattribs(attrib_name):
    query_data = []
    query = dbq.get_discogs_attribs.format(attrib_name)
    dbattribs = dbq.exec_db_query(query,  qty='all')

    for idx1 in range(len(dbattribs)):
        row = eval(dbattribs[idx1][0])
        if row != None:
            for idx2 in range(len(row)):
                query_data.append(row[idx2])

    query_data = list(zip(set(query_data)))
    insert_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    query_data = [ (attrib_name,) + xs + (insert_date,) for xs in query_data]
    query = dbq.insert_attribs_tmp
    dbq.exec_db_query(query, query_data, query_type="insert", query_many="yes")

    # insert new genres
    dbq.exec_db_query(dbq.update_attribs)

    # Truncate temp table
    dbq.exec_db_query(dbq.truncate_attribs_tmp)

def getinstancelist():
    """
    Get the list of albums from discogs_instance_import
    """
    dbcursor_dict.execute(dbq.get_all_instance_list,  )
    db_instance_list = dbcursor_dict.fetchall()
    return db_instance_list

def getcustomfields():
    """
    Grab the discogs custom fields and insert/update the db
    """
    for idx in range(len(user.collection_fields)):
        query = None

        #  Check field table for field
        db_instance = dbq.exec_db_query_dict(dbq.get_field, user.collection_fields[idx].id)

        if db_instance == None:
            query = dbq.custom_field_insert
            query_data = {'field_id': user.collection_fields[idx].id,
                                     'field_name': user.collection_fields[idx].name, 
                                     'insert_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S')  }

        elif db_instance['field_name'] != user.collection_fields[idx].name :
            query = dbq.custom_field_update
            query_data = {'field_id': user.collection_fields[idx].id,
                                     'field_name': user.collection_fields[idx].name, 
                                     'update_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S') }

        if query != None:
            dbq.exec_db_query(query, query_data, query_type='insert')



if __name__ == "__main__":
    migrate_discogs()
    sys.exit(0)

