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

from xml.etree import ElementTree as eTree
from signxml import XMLSigner
import signxml


class NfeSigner(object):
    NAMESPACE_NFE = "http://www.portalfiscal.inf.br/nfe"

    def __init__(self, key_path, certificate_path):
        self.certificate_key = open(key_path, "rb").read().replace("\r\n", "\n")
        self.certificate_cert = open(certificate_path, "rb").read().replace("\r\n", "\n")

    def sign_xml(self, xml, tag_to_sign, parameter_to_sign):
        # type: (str, str, str) -> str
        eTree.register_namespace('', NfeSigner.NAMESPACE_NFE)
        root = eTree.XML(xml)
        xml_parameter = root.find("{{{0}}}{1}".format(NfeSigner.NAMESPACE_NFE, tag_to_sign)).attrib[parameter_to_sign]
        signed_root = XMLSigner(
            method=signxml.methods.enveloped, signature_algorithm=u'rsa-sha1', digest_algorithm=u'sha1',
            c14n_algorithm=u'http://www.w3.org/TR/2001/REC-xml-c14n-20010315').sign(
            root, key=self.certificate_key, cert=self.certificate_cert, reference_uri=xml_parameter)
        return eTree.tostring(signed_root).replace("\n", "")

    def sign_cancel_xml(self, xml):
        # type: (str) -> str
        eTree.register_namespace('', NfeSigner.NAMESPACE_NFE)
        root = eTree.XML(xml)
        element = root.find("{{{0}}}evento".format(NfeSigner.NAMESPACE_NFE))
        xml_attribute = root.find("{{{0}}}evento/{{{0}}}infEvento".format(NfeSigner.NAMESPACE_NFE)).attrib['Id']
        signed_element = XMLSigner(
            method=signxml.methods.enveloped, signature_algorithm=u'rsa-sha1', digest_algorithm=u'sha1',
            c14n_algorithm=u'http://www.w3.org/TR/2001/REC-xml-c14n-20010315').sign(
            element, key=self.certificate_key, cert=self.certificate_cert, reference_uri=xml_attribute)

        root.remove(element)
        root.append(signed_element)
        return eTree.tostring(root).replace("\n", "")

    def get_signature(
        self,   # type: NfeSigner
        nfe,    # type: unicode
    ):
        # type: (...) -> unicode

        eTree.register_namespace('', NfeSigner.NAMESPACE_NFE)
        root = eTree.XML(nfe)
        nfe_id = root.find("{{{0}}}infNFe".format(NfeSigner.NAMESPACE_NFE)).attrib['Id']
        signer = signxml.XMLSigner(
            method=signxml.methods.enveloped,
            signature_algorithm="rsa-sha1",
            digest_algorithm="sha1",
            c14n_algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
        )
        signed_root = signer.sign(
            data=root,
            key=self.certificate_key,
            cert=self.certificate_cert,
            reference_uri=nfe_id,
        )
        signature = eTree.tostring(signed_root.find("Signature"))
        return signature.replace("\n", "")
