"""
Downloader for Reddit takes a list of reddit users and subreddits and downloads content posted to reddit either by the
users or on the subreddits.


Copyright (C) 2017, Kyle Hickey


This file is part of the Downloader for Reddit.

Downloader for Reddit is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Downloader for Reddit is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Downloader for Reddit.  If not, see <http://www.gnu.org/licenses/>.
"""


import xml.etree.cElementTree as et
from xml.dom import minidom
import logging

from ...Utils.SystemUtil import epoch_to_str


logger = logging.getLogger(__name__)


def export_posts_to_xml(post_list, file_path):
    """
    Exports the supplied list of posts to an xml format with each xml element representing one post with all of its
    attributes.
    :param post_list: The list of posts that are to be formatted into an xml file.
    :param file_path: The path at which the xml file will be created.
    """
    root = et.Element('failed_posts')
    for post in post_list:
        make_post_element(root, post)
    xml = minidom.parseString(et.tostring(root)).toprettyxml(indent='    ')
    with open(file_path, 'a', encoding='utf-8') as file:
        file.write(xml)
    logger.info('Exported post list to xml file', extra={'export_count': len(post_list)})


def make_post_element(parent, post):
    """
    Creates an xml element from the supplied posts attributes.
    :param parent: The parent xml element that the created xml element will be a child of.
    :param post: The post that is to be formatted into an xml element.
    """
    post_element = et.SubElement(parent, 'post')
    et.SubElement(post_element, 'author').text = post.author
    et.SubElement(post_element, 'subreddit').text = post.subreddit
    et.SubElement(post_element, 'title').text = post.title
    et.SubElement(post_element, 'created', epoch=str(int(post.created)), timestamp=post.date_posted)
    et.SubElement(post_element, 'url').text = post.url
    et.SubElement(post_element, 'status').text = post.status
    et.SubElement(post_element, 'save_status').text = post.save_status


def export_reddit_objects_to_xml(object_list, file_path):
    """
    Exports the supplied list of RedditObjects to an xml format with each xml element representing one reddit object
    with all of its relevant and formattable attributes.  Some attributes are omitted from export either due to the
    resulting file size or irrelevancy.
    :param object_list: A list of RedditObjects which are to be exported to an xml file.
    :param file_path: The path at which the xml file will be created.
    """
    root = et.Element('reddit_objects')
    user_root = et.SubElement(root, 'users')
    subreddit_root = et.SubElement(root, 'subreddits')
    for ro in object_list:
        if ro.object_type == 'USER':
            make_reddit_object_element(user_root, ro)
        else:
            make_reddit_object_element(subreddit_root, ro)
    xml = minidom.parseString(et.tostring(root)).toprettyxml(indent='    ')
    with open(file_path, mode='a', encoding='utf-8') as file:
        file.write(xml)
    logger.info('Exported reddit object list to xml file', extra={'export_count': len(object_list)})


def make_reddit_object_element(parent, ro):
    """
    Creates an xml element from the supplied RedditObjects attributes.
    :param parent: The parent xml object that the created xml element will be a child of.
    :param ro: The RedditObject which is to be formatted into an xml element.
    """
    ro_element = et.SubElement(parent, '%s' % ro.object_type.lower())
    et.SubElement(ro_element, 'name').text = ro.name
    et.SubElement(ro_element, 'version').text = ro.version
    et.SubElement(ro_element, 'save_path').text = ro.save_path
    et.SubElement(ro_element, 'post_limit').text = str(ro.post_limit)
    et.SubElement(ro_element, 'avoid_duplicates').text = str(ro.avoid_duplicates)
    et.SubElement(ro_element, 'download_videos').text = str(ro.download_videos)
    et.SubElement(ro_element, 'download_images').text = str(ro.download_images)
    et.SubElement(ro_element, 'nsfw_filter').text = ro.nsfw_filter
    et.SubElement(ro_element, 'name_downloads_by').text = ro.name_downloads_by
    et.SubElement(ro_element, 'subreddit_save_method').text = ro.subreddit_save_method
    et.SubElement(ro_element, 'date_limit', epoch=str(ro.date_limit), timestamp=str(epoch_to_str(ro.date_limit)))
    et.SubElement(ro_element, 'custom_date_limit', epoch=str(ro.custom_date_limit),
                  timestamp=str(epoch_to_str(ro.custom_date_limit)))
    et.SubElement(ro_element, 'added_on', epoch=str(ro.user_added), timestamp=str(epoch_to_str(ro.user_added)))
    et.SubElement(ro_element, 'do_not_edit').text = str(ro.do_not_edit)
    et.SubElement(ro_element, 'save_undownloaded_content').text = str(ro.save_undownloaded_content)
    et.SubElement(ro_element, 'download_enabled').text = str(ro.enable_download)