"""
This module contains simple classes to export receipts in the DEP format.
"""
from builtins import int

import json

import utils

class DEPExporterI(object):
    """
    The base class for DEP exporters. It contains functions every exporter
    must implement. Do not use this directly.
    """

    def addGroup(self, receipt_tuples, cert=None, cert_chain=[]):
        """
        Adds a new group to the DEP exporter.
        :param receipt_tuples: A list of tuples containing the algorithm ID
        for a receipt in the second and the actual receipt object in the
        first element.
        :param cert: The certificate object used for the group, or None if
        no certificate is supposed to show up in the DEP.
        :param cert_chain: A list of certificate objects containing the
        chain of signing certificates used for the group.
        """
        raise NotImplementedError("Please implement this yourself.")

    def export(self):
        """
        Creates a DEP containing the previously added groups.
        :return: The DEP as an exporter specific type.
        """
        raise NotImplementedError("Please implement this yourself.")

class DEPExporter(DEPExporterI):
    """
    A primitive DEP exporter. It generates one group of receipts as a
    dictionary structure.
    """

    def __init__(self):
        self.groups = []

    def addGroup(self, receipt_tuples, cert=None, cert_chain=[]):
        self.groups.append({
            'receipts': receipt_tuples,
            'cert': cert,
            'cert_chain': cert_chain,
        })

    def export(self):
        dep_groups = list()
        for g in self.groups:
            cert = utils.exportCertToPEM(g['cert']) if g['cert'] else ""
            cert_chain = [utils.exportCertToPEM(c) for c in
                    g['cert_chain']]
            dep_groups.append({
                "Signaturzertifikat": cert,
                "Zertifizierungsstellen": cert_chain,
                "Belege-kompakt": [r[0].toJWSString(r[1]) for r in
                    g['receipts']],
            })
        return { "Belege-Gruppe": dep_groups }

class JSONExporter(DEPExporter):
    """
    Exports a DEP to JSON format. It has the same limitations as
    DEPExporter.
    """

    def export(self):
        return json.dumps(super(JSONExporter, self).export(),
                sort_keys=False, indent=2)

# Supports no certs and no groups
class CSVExporter(DEPExporterI):
    """
    Exports a DEP to CSV format.
    """

    def __init__(self):
        self.receipts = []

    def addGroup(self, receipt_tuples, cert=None, cert_chain=[]):
        self.receipts.extend(receipt_tuples)

    def export(self):
        ret = 'Alg+ZDA;Register ID;Receipt ID;Date+Time;Sum A;Sum B;Sum C;Sum D;Sum E;Turnover Counter;Cert. Serial;Chaining Value;Signature'
        for r in self.receipts:
            ret = ret + '\n' + r[0].toCSV(r[1])
        return ret

@@ -1168,16 +1168,323 @@
 elf.%22)%0A%0A
+    def addExtra(self, key, value):%0A        %22%22%22%0A        Adds an extra item to the DEPs main dictionary.%0A        :param key: The key under that the extra data will be stored.%0A        :param value: The value of the extra data.%0A        %22%22%22%0A        raise NotImplementedError(%22Please implement this yourself.%22)%0A%0A
 class DE
@@ -1665,24 +1665,52 @@
 .groups = %5B%5D
+%0A        self.extra = dict()
 %0A%0A    def ad
@@ -1796,123 +1796,42 @@
 end(
-%7B%0A            'receipts': receipt_tuples,%0A            'cert': cert,%0A            'cert_chain': cert_chain,%0A        %7D
+(receipt_tuples, cert, cert_chain)
 )%0A%0A 
@@ -1956,22 +1956,17 @@
 M(g%5B
-'cert'
+1
 %5D) if g%5B
 'cer
@@ -1965,14 +1965,9 @@
 f g%5B
-'cert'
+1
 %5D el
@@ -2035,43 +2035,12 @@
 c in
-%0A                    g%5B'cert_chain'
+ g%5B2
 %5D%5D%0A 
@@ -2261,18 +2261,9 @@
   g%5B
-'receipts'
+0
 %5D%5D,%0A
@@ -2277,16 +2277,17 @@
      %7D)%0A
+%0A
         
@@ -2289,19 +2289,18 @@
      ret
-urn
+ =
  %7B %22Bele
@@ -2323,16 +2323,135 @@
 groups %7D
+%0A        ret.update(self.extra)%0A        return ret%0A%0A    def addExtra(self, key, value):%0A        self.extra%5Bkey%5D = value
 %0A%0Aclass 
@@ -3228,28 +3228,78 @@
 SV(r%5B1%5D)%0A        return ret%0A
+%0A    def addExtra(self, key, value):%0A        pass%0A

Allow appending of extra data to DEPs