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

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

class XmlCatalog(dict):
  def __init__(self, pScriptDirPath):
    vMainCatalogPath = System.String.Empty
    vPossiblePath = System.String.Empty
    vDirectoryInfo = None
    
    vMainCatalogPath = Path.Combine(Path.GetDirectoryName(pScriptDirPath, 'catalog.xml'))
    
    if File.Exists(vMainCatalogPath):
      self._fReadCatalog(vMainCatalogPath)
      
    vDirectoryInfo = DirectoryInfo(pScriptDirPath)
    
    for vDirectory in vDirectoryInfo.GetDirectories():
      vPossiblePath = Path.Combine(vDirectory.FullName, 'catalog.xml')
      
      if File.Exists(vPossiblePath):
        self._fReadCatalog(vPossiblePath)

  def _fReadCatalog(self, pPath):
    vSettings = None
    vReader = None
    vDocument = None
    vNavigator = None
    vIterator = None
    
    vSettings = System.Xml.XmlReaderSettings()
    vReader = System.Xml.XmlReader.Create(pPath, vSettings)
    vDocument = System.Xml.XPath.XPathDocument(vReader, System.Xml.XmlSpace.Default)
    
    vNavigator = vDocument.CreateNavigator()
    
    vIterator = vNavigator.Select('/node()/node()')
    
    while vIterator.MoveNext():
      vPublicIdAttribute = vIterator.Current.SelectSingleNode('./@public-id')
      vSystemUriAttribute = vIterator.Current.SelectSingleNode('./@system-uri')
      self[vPublicIdAttribute.Value] = vSystemUriAttribute.Value

  def ResolveSystemUri(self, pUriString):
    vResult = None
    
    if pUriString.StartsWith('http:') or \
       pUriString.StartsWith('https:') or \
       pUriString.StartsWith('file:'):
      vResult = pUriString
      
    else:
      vPossibleUriString = ''
      vSystemUriBaseName = Path.GetFileName(pUriString)
      
      for vUriString in self.itervalues():
        if vUriString.find(vSystemUriBaseName) > -1:
          vPossibleUriString = vUriString
          break

      if vPossibleUriString != '':
        vResult = vPossibleUriString

    return vResult