"""
 This module represents overrides of the System.Xml.XmlResolver
 class for resolving external references.
"""

import clr
clr.AddReference('System.Xml')
import System
import System.Uri
import System.Xml
from System.IO import Path
from System.IO import File

class EmptyUrlResolver(System.Xml.XmlUrlResolver):
  def __init__(self, ParamSourceUriAsString, ParamRootDirectory):
    self.mEmptyUri = System.Uri(Path.Combine(Path.GetDirectoryName(__file__), 'empty.xml'))
    
    self.mSourceUriAsString = ParamSourceUriAsString
    if (len(self.mSourceUriAsString) > 0):
      self.mSourceUri = System.Uri(self.mSourceUriAsString);
    else:
      self.mSourceUri = self.mEmptyUri;

  def ResolveUri(self, ParamBaseUri, ParamUriToResolveAsString):
    VarResult = None;
    
    if (ParamUriToResolveAsString == self.mSourceUriAsString) or \
       (ParamUriToResolveAsString == self.mSourceUri.AbsoluteUri):
      VarResult = self.mSourceUri;
    else:
      VarResult = self.mEmptyUri;
    
    return VarResult;
  
class ValidationResolver(System.Xml.XmlUrlResolver):
  def __init__(self, pSourceUriAsString):
    self._EmptyUri = System.Uri(Path.Combine(Path.GetDirectoryName(__file__), 'empty.xml'))
    self._XmlCatalog = (Path.GetDirectoryName(__file__))
    self._SourceUriAsString = pSourceUriAsString
    self._SourceUri = ''
    if len(self._SourceUriAsString) > 0:
      self._SourceUri = System.Uri(self._SourceUriAsString)
      
  def ResolveUri(self, pBaseUri, pUriToResolveAsString):
    vResult = None
    
    vCombinedPath = Path.Combine(Path.GetDirectoryName(self._SourceUriAsString, pUriToResolveAsString))
    
    if self.UnescapeRelativeUriBody(pUriToResolveAsString) == self.UnescapeRelativeUriBody(self._SourceUriAsString) or \
       self.UnescapeRelativeUriBody(pUriToResolveAsString) == self._SourceUri.AbsoluteUri:
      vResult = self._SourceUri
    
    elif File.Exists(vCombinedPath):
      vResult = System.Uri(vCombinedPath)
      
    elif self._XmlCatalog.ContainsKey(pUriToResolveAsString):
      vResult = System.Uri(self._XmlCatalog[pUriToResolveAsString])
    
    else:
      vPossibleUriString = System.String.Empty
      
      for vUriString in self._XmlCatalog.Values:
        if vUriString.find(pUriToResolveAsString) > -1:
          vPossibleUriString = vUriString
          break
        
      if vPossibleUriString != System.Empty:
        vResult = System.Uri(vPossibleUriString)
      else:
        vResolver = System.Xml.XmlUrlResolver()
        vResult = vResolver.ResolveUri(pBaseUri, pUriToResolveAsString)
        
    if vResult is not None:
      pass
    else:
      vResult = self._EmptyUri
      
    return vResult
    
  def UnescapeRelativeUriBody(self, pUriString):
    vResult = pUriString
    vResult = vResult.Replace('%3C', '<')
    vResult = vResult.Replace('%3E', '>')
    vResult = vResult.Replace('%23', '#')
    vResult = vResult.Replace('%22', '"')
    vResult = vResult.Replace('%20', ' ')
    vResult = vResult.Replace('%25', '%')
    
    return vResult