# IndexGen is the index generator for the static website.
import argparse
import datetime
import jinja2
import glob
import yaml
import sys
import os
from dateutil import parser as dateparser

def parse_date(date_value):
    """Parse date from string or return date object as-is."""
    if isinstance(date_value, (datetime.date, datetime.datetime)):
        return date_value
    if isinstance(date_value, str) and date_value:
        return dateparser.parse(date_value)
    return datetime.datetime.min

def directory_exists(directory) -> bool:
    return os.path.exists(directory)

def find_articles(resources) -> list:
    articles = []
    articles_dir = os.path.join(resources, 'articles')
    if not directory_exists(articles_dir):
        print('The articles directory does not exist.')
        os._exit(1)
    for article in glob.glob(os.path.join(articles_dir, '*.md')):
        if os.path.exists(article):
            with open(article, 'r') as file:
                print(article)
                article_data = yaml.load_all(file, Loader=yaml.SafeLoader)
                # get only first element out of the generator
                article_data = next(article_data)
                # articles marked "unlisted: true" are built and deployed at
                # their URL but never shown on the index page
                if article_data.get('unlisted'):
                    continue
                #  append link to the article
                article_data['link'] = f"/articles/{os.path.basename(article).replace('.md', '.html')}"
                articles.append(article_data)
    # Sort by date, newest first
    articles.sort(key=lambda x: parse_date(x.get('date')), reverse=True)
    return articles

def find_advisories(resources) -> list:
    advisories = []
    advisories_dir = os.path.join(resources, 'advisory')
    if not directory_exists(advisories_dir):
        print('The advisories directory does not exist.')
        os._exit(1)
    for advisory in glob.glob(os.path.join(advisories_dir, '*.txt')):
        if os.path.exists(advisory):
            with open(advisory, 'r') as file:
                advisory_data = yaml.load_all(file, Loader=yaml.SafeLoader)
                # get only first element out of the generator
                advisory_data = next(advisory_data)
                #  append link to the advisory
                advisory_data['link'] = f"/advisory/{os.path.basename(advisory)}"
                advisories.append(advisory_data)
    # Sort by date, newest first
    advisories.sort(key=lambda x: parse_date(x.get('date')), reverse=True)
    return advisories

def find_projects(resources) -> list:
    projects = []
    projects_dir = os.path.join(resources, 'projects')
    if not directory_exists(projects_dir):
        print('The projects directory does not exist.')
        os._exit(1)
    for project in glob.glob(os.path.join(projects_dir, '*.yaml')):
        if os.path.exists(project):
            with open(project, 'r') as file:
                project_data = yaml.load_all(file, Loader=yaml.SafeLoader)
                # get only first element out of the generator
                project_data = next(project_data)
                projects.append(project_data)
    return projects

def main(args):
    parser = argparse.ArgumentParser(description='Generate index.md file for the static website.')
    parser.add_argument('--resources', type=str, help='Path to the resources directory.', required=True)
    parser.add_argument("--blog-title", type=str, help="Title of the blog", required=True)
    parser.add_argument("--blog-author", type=str, help="Author of the blog", required=True)
    args = parser.parse_args(args)

    # check if the resources directory exists
    resources = args.resources

    if not directory_exists(resources):
        print('The resources directory does not exist.')
        os._exit(1)

    articles = find_articles(resources)
    advisories = find_advisories(resources)
    projects = find_projects(resources)
    blog = {
        'title': args.blog_title,
        'author': args.blog_author,
        # format the date like Thursday, 1 January 2021
        'update_date': datetime.datetime.now().strftime('%A, %d %B %Y')
    }

    template = os.path.join(os.path.dirname(__file__), 'index.md')
    with open(template, 'r') as file:
        tmpl = jinja2.Template(file.read())
        with open(os.path.join(resources, "pages", "index.md"), 'w') as file:
            file.write(tmpl.render(articles=articles, advisories=advisories, projects=projects, blog=blog))

if __name__ == '__main__':
    main(sys.argv[1:])
