from rdflib import Namespace, URIRef
from rdflib.plugins.shared.jsonld.context import Context


class NamespacelikeContext(Context):
    """
    Extends Context Class of jsonld plugin to provide methods that yield terms defined by a given context
    in the form of Dictionaries containing URIRefs or Namespaces respectively. Those dicts can be used
    similarly to Namespaces provided by rdflib (e.g. RDFS, DCTERMS, SOSA, etc.)
    """
    def get_namespaces_urirefs(self):
        namespaces = {}
        urirefs = {}

        namespace_iris = [iri for iri, _ in self._prefixes.items()]  # iris ending in ":", "/", "?", "#", "[", "]", "@"
        for key, val in self.to_dict().items():
            if key in ["@base", "xml"]:  # xml namespace does not end in ":", "/", "?", "#", "[", "]", "@"
                namespaces[key] = Namespace(val)
                continue
            if val in namespace_iris:
                namespaces[key] = Namespace(val)
                continue
            # we need to handle terms that are defined like {"@id": IRI, @type: IRI}
            if isinstance(val, dict):
                if "@id" not in val.keys():
                    raise LookupError(f"expected '@id' in term {key}: {val}")
                if isinstance(val["@id"], dict):
                    raise LookupError(f"expected value of '@id' in term {key}: {val} to be str, not dict")
                urirefs[key] = URIRef(val["@id"])
                continue
            urirefs[key] = URIRef(val)

        return namespaces, urirefs

    def to_dict_namespaces_urirefs(self):
        namespaces, urirefs = self.get_namespaces_urirefs()
        return namespaces | urirefs

    def to_dict_namespaces(self):
        namespaces, _ = self.get_namespaces_urirefs()
        return namespaces

    def to_dict_urirefs(self):
        _, urirefs = self.get_namespaces_urirefs()
        return urirefs


# use local snapshot of https://w3id.org/nfdi4ing/metadata4ing/m4i_context.jsonld
m4i_context = NamespacelikeContext(source="m4i_context.jsonld")
M4I = m4i_context.to_dict_urirefs()
M4I_NAMESPACES = m4i_context.to_dict_namespaces()
