# -*- coding: utf-8 -*-
"""
utils.py

Contains utility functions used in various parts of the library
"""
import os
from os.path import isfile
import re

def traverse(edxobj):
    """
    Returns a generator that traverses a given object and all its children recursively

    This allows routines to traverse an entire course by using:
    for obj in traverse(course):
        (do something with every obj in the course)

    :param edxobj: EdxObject to traverse
    :return: Generator of EdxObjects
    """
    # Don't traverse broken objects
    if edxobj.broken:
        return

    # Generate this object
    yield edxobj

    # Generate every object generated by the children of this object
    for child in edxobj.children:
        for entry in traverse(child):
            yield entry

def check_static_file_exists(course, filename):
    """
    Checks that a given file exists in the static directory.

    :param course: Course object, needed to extract directory
    :param filename: Filename to look for
    :return: True/False
    """
    fullpath = os.path.join(course.directory, "static", filename)
    return isfile(fullpath)


# Copied from the edx-platform xmodule.fields library
TIMEDELTA_REGEX = re.compile(r'^((?P<days>\d+?) day(?:s?))?(\s)?((?P<hours>\d+?) hour(?:s?))?(\s)?((?P<minutes>\d+?) minute(?:s)?)?(\s)?((?P<seconds>\d+?) second(?:s)?)?$')

def validate_graceperiod(entry):
    """Returns True if entry is a valid grace period"""
    if entry is None:
        return True
    parts = TIMEDELTA_REGEX.match(entry)
    if not parts:
        return False
    return True

def find_links(edxobj):
    """Find all internal links in the given object"""
    links = []

    # This is the list of all attributes we will scan for internal links
    url_attributes = ['link', 'src', 'href', 'img', 'icon', 'preprocessorSrc']
    # This is the list of special links we will look for
    internal_links = ['/static/', '/course/', '/jump_to_id/']

    # Search for all elements that have the desired attributes
    if edxobj.content is not None:  # Empty objects are stored as None
        for attrib in url_attributes:
            for tag in edxobj.content.findall(f".//*[@{attrib}]"):
                link = tag.get(attrib)
                if link:
                    for special in internal_links:
                        if link.startswith(special):
                            links.append(link)

    return links
