"""Common/shared utilities
"""
import logging
import os

import smtk
import smtk.model


# ---------------------------------------------------------------------
def passes_categories(item, categories):
    """Backward- and list/set-compatible category check

    The isMemberOf() method was deleted early Jan 2020.
    There is also some uncertainty whether the API argument
    should be a list or set.
    """
    if hasattr(item, 'isMemberOf'):
        if isinstance(categories, list):
            return item.isMemberOf(categories)
        # (else)
        return item.isMemberOf(list(categories))
    elif isinstance(categories, set):
        return item.categories().passes(categories)
    else:
        return item.categories().passes(set(categories))

# ---------------------------------------------------------------------
def get_model_info(scope):
    '''DEPRECATED Finds/updates model-related info on input scope object:

        * scope.model_resource
        * scope.model_ent
        * scope.model_file
        * scope.model_path
    '''
    scope.model_resource = scope.sim_atts.refModelResource()
    mask = int(smtk.model.MODEL_ENTITY)
    model_ents = scope.model_resource.entitiesMatchingFlags(mask, True)
    #print 'model_ents', model_ents
    if not model_ents:
        msg = 'No model - cannot export'
        scope.logger.addError(msg)
        raise Exception(msg)

    if len(model_ents) > 1:
        msg = 'Multiple models - using first one'
        print('WARNING: %s' % msg)
        scope.logger.addWarning(msg)
    scope.model_ent = model_ents.pop()

    # Get path to native model from string properties
    # that *should* be on the model
    urls = scope.model_resource.stringProperty(scope.model_ent, 'url')
    if not urls:
        msg = 'Model has to string property \"url\"'
        print('ERROR: %s' % msg)
        raise Exception(msg)

    url = urls[0]
    #print 'url', url

    # Get model filename
    scope.model_file = os.path.basename(url)
    print('scope.model_file %s' % scope.model_file)

    # Get full path to model
    if os.path.isabs(url):
        scope.model_path = url
    else:
        # Path to native model is relative to .smtk model file
        smtk_urls = scope.model_resource.stringProperty(
            scope.model_ent, 'smtk_url')
        if not smtk_urls:
            msg = 'Model has no string property \"smtk_url\". Cannot get path to native model'
            print('ERROR: %s' % msg)
            raise Exception(msg)

        #print 'smtk_urls'
        smtk_url = smtk_urls[0]
        smtk_folder = os.path.dirname(smtk_url)
        model_path = os.path.join(smtk_folder, url)
        scope.model_path = os.path.abspath(model_path)
    print('scope.model_path %s' % scope.model_path)

# ---------------------------------------------------------------------
def format_vector(value_item, fmt='%g', separator=', '):
    '''Formats contents for item vector into comma-separated string

    '''
    slist = list()
    for i in range(value_item.numberOfValues()):
        s = fmt % value_item.value(i)
        slist.append(s)
    return separator.join(slist)

# ---------------------------------------------------------------------
def format_entity_string(scope, att):
    '''Generates comma-separated list of "pedigree id"s for model associations

    Returns None if no associations found
    '''
    ent_idlist = get_entity_ids(scope, att.associations())
    if not ent_idlist:
        return None

    # (else)
    ent_string = ','.join(str(id) for id in ent_idlist)
    return ent_string

# ---------------------------------------------------------------------
def get_entity_ids(scope, model_entity_item):
    '''Returns list of "pedigree id"s for smtk::attribute::ModelEntityItem

    @param model_entity_item: might be None
    '''
    ent_idlist = list()  # return value (might be empty list)
    if model_entity_item is None:
        return ent_idlist

    for i in range(model_entity_item.numberOfValues()):
        if not model_entity_item.isSet(i):
            continue

        ent = model_entity_item.value(i)
        prop_idlist = scope.model_resource.integerProperty(ent.id(), 'pedigree id')
        if prop_idlist:
            ent_idlist.append(prop_idlist[0])

    return sorted(ent_idlist)
