# -*- coding: utf-8 -*-

from logging import debug

class InvalidUri(ValueError):
    pass


def is_alpha( c ):
    return ( ("a" <= c and c <= "z") or 
             ("A" <= c and c <= "Z") )


def is_digit( c ):
    return "0" <= c and c <= "9"


def is_unreserved( c ):
    return is_alpha(c) or is_digit(c) or -1 != "-._~".find(c)


def is_subdelimiter( c ):
    return -1 != "!$&'()*+,;=".find(c)


def is_gendelimiter( c ):
    return -1 != ":/?#[]@".find(c)


def is_reserved( c ):
    return is_gendelimiter(c) or is_subdelimiter(c)


def is_path_symbol( c ):
    return is_unreserved(c) or is_subdelimiter(c) or -1 != "%:@".find(c)


def is_start_symbol( c ):
    return ( ('a' <= c and c <= 'z') or
             ('A' <= c and c <= 'Z') )


def is_component_symbol( c ):
    return ( ('a' <= c and c <= 'z') or 
             ('A' <= c and c <= 'Z') or
             ('0' <= c and c <= '9') or
             '+' == c or
             '.' == c or
             '-' == c )


def scheme_end( uri ):
    uriLen = len(uri)
    if 0 == uriLen or not is_start_symbol(uri[0]):
        return -1
    end = 1
    while end < uriLen and is_component_symbol(uri[end]):
        end = 1 + end
    if uriLen == end or ':' != uri[end]:
        return -1
    return end


def scheme( otherwise, uri ):
    """Extracts the scheme component."""
    last = scheme_end(uri)
    if -1 == last:
        return otherwise
    return uri[0:last].lower()


def authority_begin( uri, offset ):
    offset += 1 # skip past the ':'  
    if '//' == uri[offset:2+offset]:
        offset += 2
    return offset


def authority_end( uri, offset ):
    last = uri.find('/',offset)
    if -1 == last:
        return hierarchy_end(uri,offset)
    return last


def authority( uri ):
    """Extract the authority component."""
    first = authority_begin(uri,scheme_end(uri))
    last = authority_end(uri,first)
    return uri[first:last]


def service_end( uri ):
    return authority_end(uri,authority_begin(uri,scheme_end(uri)))


def hierarchy_end( uri, offset ):
    query = uri.find('?',offset)
    fragment = uri.find('#',offset)
    if -1 == query:
        if -1 == fragment:
            return len(uri)
        else:
            return fragment
    elif -1 == fragment:
        return query
    elif query < fragment:
        return query
    return fragment


def path( uri ):
    """Extracts the rootless path component."""
    first = service_end(uri)
    last = hierarchy_end(uri,first)
    if last == first:
        return ""
    return uri[1+first:last]


def query( otherwise, uri ):
    """Extract the query component."""
    first = uri.find('?')
    if -1 == first:
        return otherwise
    last = uri.find('#')
    if -1 == last:
        return uri[1+first:]
    elif last < first:
        return uri[1+first:last]
    return otherwise


def fragment( otherwise, uri ):
    """Extracts the fragment component."""
    first = uri.find('#')
    if -1 == first:
        return otherwise
    return uri[1+first:]


def proxy( uri ):
    """Extracts the proxy request URI."""
    last = uri.find('#')
    if -1 == last:
        return uri  
    return uri[:last]


def service( uri ):
    """Extracts the remote service identifier."""
    return uri[:service_end(uri)]


def request( uri ):
    """Extracts the request URI."""
    first = service_end(uri)
    last = uri.find('#',first)
    if -1 == last:
        return uri[first:]
    return uri[first:last]


def resolve( base, relative ):
  """Resolves a relative URI."""
  from path import vet as path_vet

  if "" == relative:
    return proxy(base)
    
  if "#" == relative[0]:
    hierarchy = proxy(base)
    tail = relative
  elif "?" == relative[0]: