
# REST collection resources tree
resources_tree = {
    'projects'        :['subjects', 'resources'],
    'subjects'        :['experiments', 'resources'],
    'experiments'     :['assessors', 'reconstructions', 'scans', 'resources'],
    'assessors'       :['resources', 'in_resources','out_resources'],
    'reconstructions' :['in_resources','out_resources'],
    'scans'           :['resources'],
    'resources'       :['files'],
    'files'           :[],
    'in_resources'    :['files'],
    'in_files'        :[],
    'out_resources'   :['files'],
    'out_files'       :[],
    }

prearc_tree = {'projects'   :['scans'],
               'scans'      :['resources'],
               'resources'  :['files']
               }
# REST resources that are not natively supported
extra_resources_tree = {'projects':['assessors', 'scans', 'reconstructions'],
                        'subjects':['assessors', 'scans', 'reconstructions'],
                        }

# REST <Python to URI> translation table 
rest_translation = {'in_resources':'in/resources',
                    'in_files':'in/files',
                    'out_resources':'out/resources',
                    'out_files':'out/files',
                    'in_resource':'in/resource',
                    'in_file':'in/file',
                    'out_resource':'out/resource',
                    'out_file':'out/file',
                    }



# REST json format <id_header, label_header>
json = {'projects':['ID', 'ID'],
        'subjects':['ID', 'label'],
        'experiments':['ID', 'label'],
        'assessors':['ID', 'label'],
        'reconstructions':['ID', 'label'],
        'scans':['ID', 'ID'],
        'resources':['xnat_abstractresource_id', 'label'],
        'out_resources':['xnat_abstractresource_id', 'label'],
        'in_resources':['xnat_abstractresource_id', 'label'],
        'files':['path', 'path'],
        }

resources_singular = [key.rsplit('s', 1)[0] for key in resources_tree.keys()]
resources_plural   = resources_tree.keys()
resources_types    = resources_singular + list(resources_plural)

default_datatypes = {'projects':'xnat:projectData',
                     'subjects':'xnat:subjectData',
                     'experiments':'xnat:mrSessionData',
                     'assessors':'xnat:mrAssessorData',
                     'reconstructions':'xnat:reconstructedImageData',
                     'scans':'xnat:mrScanData',
                     'resources':None,
                     'in_resources':None,
                     'out_resources':None,
                     }

def datatype_attributes(root, datatype):
    def _iterchildren(node, pathsofar):
        elements = []

        for child in node.iterchildren():
            if isinstance(child.tag, basestring) \
                and child.tag.split('}')[1] == 'element':
                    elements.append('%s/%s'%(pathsofar, child.get('name')))
                    elements.extend(_iterchildren(child, '%s/%s'%
                                        (pathsofar, child.get('name')))
                                    )

            elif isinstance(child.tag, basestring) \
                and child.tag.split('}')[1] == 'attribute':
                    elements.append('%s/%s'%(pathsofar, child.get('name')))

            elif isinstance(child.tag, basestring) \
                    and child.tag.split('}')[1] == 'extension':
                
                ct_xpath = "/xs:schema/xs:complexType[@name='%s']"% \
                    child.get('base').split(':')[1]

                for complex_type in node.getroottree(
                    ).xpath(ct_xpath, namespaces=child.nsmap):

                    same = False

                    for ancestor in child.iterancestors():
                        if ancestor.get('name') == \
                                child.get('base').split(':')[1]:
                            same = True
                            break

                    if not same:
                        elements.extend(_iterchildren(complex_type, 
                                                      pathsofar)
                                        )

                    elements.extend(_iterchildren(child, pathsofar))

            else:
                elements.extend(_iterchildren(child, pathsofar))

        return elements

    ct_xpath = "/xs:schema/xs:complexType[@name='%s']" % \
        datatype.split(':')[1]

    attributes = []

    for complex_type in root.xpath(ct_xpath, namespaces=root.nsmap):
        for child in complex_type.iterchildren():                
            attributes.extend(_iterchildren(child, datatype))

    return attributes

def datatypes(root):
    nsmap = get_nsmap(root)

    return [element.get('type')
            for element in root.xpath('/xs:schema/xs:element', 
                                      namespaces=nsmap)
            ]

def get_nsmap(node):
    nsmap = node.nsmap
    none_ns = node.nsmap.get(None)

    if none_ns != None:
        nsmap[none_ns.rsplit('/', 1)[1]] = none_ns
        del nsmap[None]

    return nsmap

def class_name(self):
    """
    Return the name of this class without qualification.
    eg. If the class name is "x.y.class" return only "class"
    """
    return self.__class__.__name__.split('.')[-1]
