import sys
import os
import zipfile
import time
import datetime
import json
import logging

from xml.dom import minidom
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement, Comment

# Get an instance of a logger
logger = logging.getLogger('django')

sample_json = """
{"offers":
  [
    {
      "SellerProductId": "4250755391922.",
      "ProductEan": "4250755391922",
      "Price": "289.50",
      "Stock": 5
    },
    {
      "SellerProductId": "4250755391946.",
      "ProductEan": "4250755391946",
      "Price": "249.50",
      "Stock": 5
    },
    {
      "SellerProductId": "4250755391557.",
      "ProductEan": "4250755391557",
      "Price": "234.50",
      "Stock": 5
    }
  ]
}
"""


def prettify(elem):
    """
    :param elem:
    :return: a pretty-printed XML string for the Element
    """
    rough_string = ElementTree.tostring(elem, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="  ")


def create_xml(offers_json):
    """
    The API quota are applied on the number of call to the methods by hour.
    The counter of call is reinitialized every hour.

    If you include more than 300 000 offers in your package you are not sure that your package will be integrated.
    Our advise is to stay below 200 000 offers in your package.
    :return:
    """
    top = Element('OfferPackage', Name="Nom fichier offres", PurgeAndReplace="false", PackageType="Full",
                  xmlns="clr-namespace:Cdiscount.Service.OfferIntegration.Pivot;assembly=Cdiscount.Service.OfferIntegration")
    # top.set('xmlns: x', "http://schemas.microsoft.com/winfx/2006/xaml")

    loaded_json = json.loads(offers_json, strict=False)
    items = loaded_json["offers"]
    offers = SubElement(top, 'OfferPackage.Offers')
    offer_collection = SubElement(offers, 'OfferCollection', Capacity="%d" % len(items))
    for offer in items:
        offer_xml = SubElement(offer_collection, 'Offer',
                           SellerProductId="%s" % offer["SellerProductId"],
                           ProductEan="%s" % offer["ProductEan"],
                           Price="%s" % offer["Price"],
                           Stock="%d" % offer["Stock"],
                           ProductCondition='%d' % offer["ProductCondition"],
                           EcoPart='%d' % offer["EcoPart"],
                           DeaTax='%d' % offer["DeaTax"],
                           Vat='%d' % offer["Vat"],
                           PreparationTime='%d' % offer["PreparationTime"],
                           StrikedPrice="%s" % offer["StrikedPrice"],
                           Comment='%s' % offer["Comment"])
        offer_shippingInformationList = SubElement(offer_xml, 'Offer.ShippingInformationList')
        delivery_modes = offer.get("DeliveryModes", [])
        shippingInformationList = SubElement(offer_shippingInformationList, 'ShippingInformationList',
                                             Capacity='%d' % len(delivery_modes))
        for delivery_mode in delivery_modes:
                SubElement(shippingInformationList, 'ShippingInformation',
                        AdditionalShippingCharges='%d' % 0,
                        DeliveryMode='%s' % delivery_mode["legacyDeliveryModeId"],
                        ShippingCharges='%d' % 0)

    comment_offerpublicationlist = """
    the OfferPublicationList element is optional and is utilized to specify on which website the updates must be done
    by default updates are applied on Cdiscount only (Id=16 for Belgium)
    """
    comment = Comment(comment_offerpublicationlist)
    top.append(comment)

    # offer_publication_list = SubElement(top, 'OfferPackage.OfferPublicationList')
    # sub_offer_publication_list = SubElement(offer_publication_list, 'OfferPublicationList', Capacity="1")
    # # SubElement(sub_offer_publication_list, 'PublicationPool', Id="1")
    # SubElement(sub_offer_publication_list, 'PublicationPool', Id="16")
    logger.debug(prettify(top))
    source_path = os.path.dirname(os.path.abspath(__file__))
    file_path = '%s/../cdiscount_files/stockandprice/Content/Offers.xml' % source_path

    os.remove(file_path)

    time.sleep(1)
    os.sync()
    time.sleep(1)

    tree = ElementTree.ElementTree(top)
    tree.write(file_path, encoding='utf-8', xml_declaration=True)

    time.sleep(1)
    os.sync()
    time.sleep(1)


def zip_dir():
    source_path = os.path.dirname(os.path.abspath(__file__))
    timestamp = datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d%H%M%S')
    dir_path = "%s/../cdiscount_files/stockandprice" % source_path
    archive_file_name = "stockandprice_%s.zip" % timestamp
    archive_file_path = '%s/../cdiscount_files/archive/%s' % (source_path, archive_file_name)
    url_path = "archive/%s" % archive_file_name
    zipfile_handle = zipfile.ZipFile(archive_file_path, 'w', zipfile.ZIP_DEFLATED)
    for root, dirs, files in os.walk(dir_path):
        for file in files:
            file_path = os.path.join(root, file)
            if "DS_Store" in file_path:
                continue
            xxx = file_path[len(dir_path):]
            logger.debug("file is %s" % xxx)
            zipfile_handle.write(file_path, file_path[len(dir_path):])
    zipfile_handle.close()
    return url_path


def do(offers_json):
    logger.debug("%s" % offers_json)
    create_xml(offers_json)
    path = zip_dir()
    logger.info("cdiscount returns %s" % path)
    return path


if __name__ == "__main__":
    print("cdiscount is starting...")
    result = do(sample_json)
    print("cdiscount returns %s" % result)
