# Path: sofia/entity_type.py
# class EntityType(object):
#     """
#     An "entity" represents data that is processed by steps in a workflow. They can be considered nouns and the step can
#     be considered verbs.
#     """
#     def __init__(self, name, attributes=None, alias=None, format_string=''):
#         self.name = name
#         self.attributes = {} if attributes is None else attributes
#         self.alias = name if alias is None else alias
#         self.format_string = '{' + format_string + '}'
# 
#     def __str__(self):
#         res = [self.name if self.name == self.alias else '{} ({})'.format(self.alias, self.name)]
#         res.extend('{}={}'.format(k, str(v) if isinstance(v, str) else ','.join(v)) for k, v in sorted(self.attributes.items()))
#         return '\\n'.join(res)
# 
#     def __hash__(self):
#         attributes = tuple((key, frozenset(values)) for key, values in self.attributes.items())
#         return hash(self.name) + hash(attributes)
# 
#     def __eq__(self, other):
#         return self.name == other.name and self.attributes == other.attributes
# 
#     def __lt__(self, other):
#         return str(self) < str(other)
# 
#     def format(self, entity):
#         try:
#             if isinstance(entity, (set, list)):
#                 return ','.join(self.format_string.format(e) for e in entity)
#             return '' if entity is None else self.format_string.format(entity)
#         except Exception as e:
#             import sys
#             sys.stderr.write('Error formatting entity {}.\n'.format(self.name))
#             sys.stderr.write('Format string: {}.\n'.format(self.format_string))
#             sys.stderr.write('Entity: {}.\n'.format(entity))
#             sys.stderr.write('Error: {}\n'.format(e))
#             #raise e
#         return ''


import os
import re
from sofia.entity_type import EntityType
    An example:
        -r /tmp/tmp.vcf
        -r "/tmp/tmp.vcf:tmp:entity=vcf"
        -r "tmp.vcf:tmp:format=vcf:x=x:y=y:chromosome_id=ucsc"
    """

    REGX = re.compile(r'(?P<entity>[^[.:]+)(?P<format_string>[^:]+)?')

    def __init__(self, extensions):
        self.extensions = extensions

    def parse_requested_entity(self, definition):
        try:
            type, alias, attributes = self.parse_definition(definition)
        except Exception:
            raise ValueError('Invalid entity definition: {}'.format(definition))

        match = self.REGX.match(type)
        if match is None:
            raise ValueError('Invalid entity type: {}'.format(type))
        type, format_string = match.groups('')
        return EntityType(type, attributes=attributes, alias=alias, format_string=format_string)

    def parse_provided_entity(self, definition):
        filename, alias, attributes = self.parse_definition(definition)
        type = self.get_type_by_extension(filename)
        attributes['filename'] = {filename}
        if alias is None:
            alias = os.path.basename(filename)
        attributes['resource'] = {alias}

# Path: sofia/entity_type.py
# class EntityType(object):
#     """
#     An "entity" represents data that is processed by steps in a workflow. They can be considered nouns and the step can
#     be considered verbs.
#     """
#     def __init__(self, name, attributes=None, alias=None, format_string=''):
#         self.name = name
#         self.attributes = {} if attributes is None else attributes
#         self.alias = name if alias is None else alias
#         self.format_string = '{' + format_string + '}'
# 
#     def __str__(self):
#         res = [self.name if self.name == self.alias else '{} ({})'.format(self.alias, self.name)]
#         res.extend('{}={}'.format(k, str(v) if isinstance(v, str) else ','.join(v)) for k, v in sorted(self.attributes.items()))
#         return '\\n'.join(res)
# 
#     def __hash__(self):
#         attributes = tuple((key, frozenset(values)) for key, values in self.attributes.items())
#         return hash(self.name) + hash(attributes)
# 
#     def __eq__(self, other):
#         return self.name == other.name and self.attributes == other.attributes
# 
#     def __lt__(self, other):
#         return str(self) < str(other)
# 
#     def format(self, entity):
#         try:
#             if isinstance(entity, (set, list)):
#                 return ','.join(self.format_string.format(e) for e in entity)
#             return '' if entity is None else self.format_string.format(entity)
#         except Exception as e:
#             import sys
#             sys.stderr.write('Error formatting entity {}.\n'.format(self.name))
#             sys.stderr.write('Format string: {}.\n'.format(self.format_string))
#             sys.stderr.write('Entity: {}.\n'.format(entity))
#             sys.stderr.write('Error: {}\n'.format(e))
#             #raise e
#         return ''


# Path: sofia/workflow_template/entity_definition_parser.py
import os
import re
from sofia.entity_type import EntityType

    An example:
        -r /tmp/tmp.vcf
        -r "/tmp/tmp.vcf:tmp:entity=vcf"
        -r "tmp.vcf:tmp:format=vcf:x=x:y=y:chromosome_id=ucsc"
    """

    REGX = re.compile(r'(?P<entity>[^[.:]+)(?P<format_string>[^:]+)?')

    def __init__(self, extensions):
        self.extensions = extensions

    def parse_requested_entity(self, definition):
        try:
            type, alias, attributes = self.parse_definition(definition)
        except Exception:
            raise ValueError('Invalid entity definition: {}'.format(definition))

        match = self.REGX.match(type)
        if match is None:
            raise ValueError('Invalid entity type: {}'.format(type))
        type, format_string = match.groups('')
        return EntityType(type, attributes=attributes, alias=alias, format_string=format_string)

    def parse_provided_entity(self, definition):
        filename, alias, attributes = self.parse_definition(definition)
        type = self.get_type_by_extension(filename)
        attributes['filename'] = {filename}
        if alias is None:
            alias = os.path.basename(filename)
        attributes['resource'] = {alias}

        return EntityType(type, attributes=attributes, alias=alias)