# Path: src/sii/lib/lib/xml.py
# XML_DECL = lambda enc: b'<?xml version="1.0" encoding="' + bytes(enc, enc) + b'"?>'
# class XML(object):
#     def __init__(self, node=None, name=None, text=None, namespaces=None):
#     def __repr__(self):
#     def __str__(self):
#     def __int__(self):
#     def __float__(self):
#     def __iter__(self):
#     def __setattr__(self, name, value):
#     def __getitem__(self, key):
#     def __setitem__(self, key, value):
#     def __remove__(self):
#     def __name__(self):
#     def __children__(self):
#     def __siblings__(self):
#     def __generation__(self):
#     def _etree(self):
#     def _xml(self):
#     def _str(self):
#     def _int(self):
#     def _float(self):
#     def _number(self):
#     def _list(self):
#     def _has(self, name):
# def create_xml(name, value=None, namespaces=None):
# def read_xml(path):
# def load_xml(xml_string):
# def wrap_xml(xml_etree):
# def dump_etree(xml_node):
# def dump_xml(xml_node, **kwargs):
# def print_xml(xml, file=sys.stdout.buffer, end='\n', encoding='UTF-8'):
# def write_xml(xml, fpath, end='\n', encoding='UTF-8', append=False):
# 
# Path: src/sii/lib/types/CAF.py
# class CAF(object):
# 
#     def __init__(self, caf_xml):
#         if isinstance(caf_xml, str):
#             self._root = etree.fromstring(caf_xml)
#         elif isinstance(caf_xml, etree._Element):
#             self._root = caf_xml
#         else:
#             raise ValueError("Expected XML string or etree.Element as argument")
# 
#     def __str__(self):
#         return etree.tostring(self._root, encoding='unicode')
# 
#     @property
#     def xml(self):
#         return self._root
# 
#     @property
#     def company_rut(self):
#         rut = self._ctrld_xpath(
#             '//RE/text()',
#             "Could not parse company RUT in CAF:\n{0}".format(str(self))
#         )
#         return rut
# 
#     @property
#     def dte_type(self):
#         typ = self._ctrld_xpath(
#             '//TD/text()',
#             "Could not parse document type in CAF:\n{0}".format(str(self))
#         )
#         return int(typ)
# 
#     @property
#     def dte_id_from(self):
#         id_from = self._ctrld_xpath(
#             '//RNG/D/text()',
#             "Could not parse range <from> in CAF:\n{0}".format(str(self))
#         )
#         return int(id_from)
# 
#     @property
#     def dte_id_until(self):
#         id_until = self._ctrld_xpath(
#             '//RNG/H/text()',
#             "Could not parse range <until> in CAF:\n{0}".format(str(self))
#         )
#         return int(id_until)
# 
#     @property
#     def private_key(self):
#         return self._ctrld_xpath(
#             '//RSASK/text()',
#             "Could not parse private key in CAF:\n{0}".format(str(self))
#         )
# 
#     @property
#     def public_key(self):
#         return self._ctrld_xpath(
#             '//RSAPUBK/text()',
#             "Could not parse public key in CAF:\n{0}".format(str(self))
#         )
# 
#     def _ctrld_xpath(self, xpath, failmsg):
#         values = self._root.xpath(xpath)
# 
#         if not values:
#             raise RuntimeError(failmsg)
#         elif len(values) > 1:
#             raise RuntimeError("Found more than one values matching "
#                                "\"{0}\" in:\n{1}".format(xpath, self.xml))
#         else:
#             return values[0]


import os
import collections
from lxml import etree
from ..lib import xml
from .CAF import CAF
            self._idx_company[rut].append(caf)

    def resolve(self, rut, dte_type, dte_id):
        """ Returns CAF if available for given <company, dte_type, dte_id> information. """
        cafs  = self._idx_company[rut]
        typed = [caf for caf in cafs if caf.dte_type == dte_type]

        for caf in typed:
            if caf.dte_id_from <= dte_id <= caf.dte_id_until:
                return caf

        raise RuntimeError(
            "Could not find CAF for document <company={0}, type={1}, id={2}>".format(rut, dte_type, dte_id)
        )

    def resolve_document(self, dte):
        """ Returns CAF if available for given DTE inner <Documento>. """
        dte = xml.wrap_xml(dte)

        dte_type = int(dte.Encabezado.IdDoc.TipoDTE)
        dte_id   = int(dte.Encabezado.IdDoc.Folio)
        rut_full = str(dte.Encabezado.Emisor.RUTEmisor)

        rut = read_rut(rut_full)

        return self.resolve(rut, dte_type, dte_id)


def _read_caf(path):
    with open(path, "rb") as fh:

# Path: src/sii/lib/lib/xml.py
# XML_DECL = lambda enc: b'<?xml version="1.0" encoding="' + bytes(enc, enc) + b'"?>'
# class XML(object):
#     def __init__(self, node=None, name=None, text=None, namespaces=None):
#     def __repr__(self):
#     def __str__(self):
#     def __int__(self):
#     def __float__(self):
#     def __iter__(self):
#     def __setattr__(self, name, value):
#     def __getitem__(self, key):
#     def __setitem__(self, key, value):
#     def __remove__(self):
#     def __name__(self):
#     def __children__(self):
#     def __siblings__(self):
#     def __generation__(self):
#     def _etree(self):
#     def _xml(self):
#     def _str(self):
#     def _int(self):
#     def _float(self):
#     def _number(self):
#     def _list(self):
#     def _has(self, name):
# def create_xml(name, value=None, namespaces=None):
# def read_xml(path):
# def load_xml(xml_string):
# def wrap_xml(xml_etree):
# def dump_etree(xml_node):
# def dump_xml(xml_node, **kwargs):
# def print_xml(xml, file=sys.stdout.buffer, end='\n', encoding='UTF-8'):
# def write_xml(xml, fpath, end='\n', encoding='UTF-8', append=False):
# 
# Path: src/sii/lib/types/CAF.py
# class CAF(object):
# 
#     def __init__(self, caf_xml):
#         if isinstance(caf_xml, str):
#             self._root = etree.fromstring(caf_xml)
#         elif isinstance(caf_xml, etree._Element):
#             self._root = caf_xml
#         else:
#             raise ValueError("Expected XML string or etree.Element as argument")
# 
#     def __str__(self):
#         return etree.tostring(self._root, encoding='unicode')
# 
#     @property
#     def xml(self):
#         return self._root
# 
#     @property
#     def company_rut(self):
#         rut = self._ctrld_xpath(
#             '//RE/text()',
#             "Could not parse company RUT in CAF:\n{0}".format(str(self))
#         )
#         return rut
# 
#     @property
#     def dte_type(self):
#         typ = self._ctrld_xpath(
#             '//TD/text()',
#             "Could not parse document type in CAF:\n{0}".format(str(self))
#         )
#         return int(typ)
# 
#     @property
#     def dte_id_from(self):
#         id_from = self._ctrld_xpath(
#             '//RNG/D/text()',
#             "Could not parse range <from> in CAF:\n{0}".format(str(self))
#         )
#         return int(id_from)
# 
#     @property
#     def dte_id_until(self):
#         id_until = self._ctrld_xpath(
#             '//RNG/H/text()',
#             "Could not parse range <until> in CAF:\n{0}".format(str(self))
#         )
#         return int(id_until)
# 
#     @property
#     def private_key(self):
#         return self._ctrld_xpath(
#             '//RSASK/text()',
#             "Could not parse private key in CAF:\n{0}".format(str(self))
#         )
# 
#     @property
#     def public_key(self):
#         return self._ctrld_xpath(
#             '//RSAPUBK/text()',
#             "Could not parse public key in CAF:\n{0}".format(str(self))
#         )
# 
#     def _ctrld_xpath(self, xpath, failmsg):
#         values = self._root.xpath(xpath)
# 
#         if not values:
#             raise RuntimeError(failmsg)
#         elif len(values) > 1:
#             raise RuntimeError("Found more than one values matching "
#                                "\"{0}\" in:\n{1}".format(xpath, self.xml))
#         else:
#             return values[0]


# Path: src/sii/lib/types/CAFPool.py
import os
import collections
from lxml import etree
from ..lib import xml
from .CAF import CAF

            self._idx_company[rut].append(caf)

    def resolve(self, rut, dte_type, dte_id):
        """ Returns CAF if available for given <company, dte_type, dte_id> information. """
        cafs  = self._idx_company[rut]
        typed = [caf for caf in cafs if caf.dte_type == dte_type]

        for caf in typed:
            if caf.dte_id_from <= dte_id <= caf.dte_id_until:
                return caf

        raise RuntimeError(
            "Could not find CAF for document <company={0}, type={1}, id={2}>".format(rut, dte_type, dte_id)
        )

    def resolve_document(self, dte):
        """ Returns CAF if available for given DTE inner <Documento>. """
        dte = xml.wrap_xml(dte)

        dte_type = int(dte.Encabezado.IdDoc.TipoDTE)
        dte_id   = int(dte.Encabezado.IdDoc.Folio)
        rut_full = str(dte.Encabezado.Emisor.RUTEmisor)

        rut = read_rut(rut_full)

        return self.resolve(rut, dte_type, dte_id)


def _read_caf(path):
    with open(path, "rb") as fh:

        xml = etree.parse(fh)