from glob import glob
import os
import shutil as sh
import numpy as np
from tqdm import tqdm
from bs4 import BeautifulSoup as bs
import argparse

DESCRIPTION = ("Convert the HTML generated by the Data 8 textbook repository "
               "into a form that can be hosted with the Data 8 course website "
               "template.")
parser = argparse.ArgumentParser(description=DESCRIPTION)
parser.add_argument("path_textbook", help="Path to the Data 8 textbook folder.")
parser.add_argument("path_course_website", help="Path to the Data 8 course website you've forked.")
args = parser.parse_args()

path_textbook = args.path_textbook
path_out = args.path_course_website

def insert_meta(lines, vals):
    # Create metadata
    meta = ['---'] + vals + ['---', '']
    meta = [ii+'\n' for ii in meta]
    for meta_line in meta[::-1]:
        lines.insert(0, meta_line)
    return lines

def take_inbetween(line, bw='()'):
    take = line.split(bw[0])[-1].split(bw[1])[0]
    return take

def create_hub_link(filepath, binder=False):
    if binder is True:
        interact_link = 'https://mybinder.org/v2/gh/data-8/textbook/gh-pages?'
        filepath_section = 'filepath={}'.format(filepath)
    else:
        interact_link = '{{ site.hub_url }}/hub/user-redirect/git-pull?repo={{ site.textbook_url }}'
        filepath_section = '&branch={{ site.textbook_branch }}' + '&subPath={}'.format(filepath)
    return interact_link + filepath_section

# Copy over readme
print('Copying course readme...')
path_readme = os.path.join(path_textbook, 'README.md')
with open(path_readme, 'r') as ff:
    lines = ff.readlines()
meta_add = ['layout: single', 'title: Introduction', 'sidebar:', '  title: "Textbook Navigation"', '  nav: sidebar-textbook']
lines = insert_meta(lines, meta_add)

with open(os.path.join(path_out, 'textbook', 'index.md'), 'w') as ff:
    ff.writelines(lines)

# Copy over summary
print('Copying course summary...')
path_summary = os.path.join(path_textbook, 'SUMMARY.md')
with open(path_summary, 'r') as ff:
    lines = ff.readlines()
lines = lines[2:]

from collections import OrderedDict

# Copy over the summary into a Jekyll sidebar structure
print('Generating textbook sidebar structure...')
summary = OrderedDict()
for line in lines:
    title = take_inbetween(line, '[]')
    link = take_inbetween(line, '()')
    level = line.find('*')

    if level == 0:
        header = title
        # Create a new title section
        if not summary.get(header):
            summary[header] = []
    new_link = link.replace('chapters/', '/textbook/')
    new_link = os.path.splitext(new_link)[0]
    summary[header].append((title, new_link))
    
navigation_yml = ['sidebar-textbook:']
for key, vals in summary.items():
    title, link = vals[0]
    navigation_yml += ['  - title: "{}"'.format(title.replace('"', "'")),
                       '    url: {}'.format(link),
                       '    children:']
    for title, link in vals[1:]:
        level = len(title.split(' ')[0].split('.')) - 1
        to_add = ['      - title: "{}"'.format(title.replace('"', "'")),
                  '        url: {}'.format(link),
                  '        class: "level_{}"'.format(level)]
        navigation_yml += to_add
navigation_yml = [ii+'\n' for ii in navigation_yml]

# Replace old sidebar section in navigation
print('Updating the course website sidebar...')
with open(os.path.join(path_out, '_data', 'navigation.yml'), 'r') as ff:
    lines = ff.readlines()

ix_nav = np.where(['sidebar-textbook' in line for line in lines])[0][0]
lines = lines[:ix_nav]
lines += navigation_yml

with open(os.path.join(path_out, '_data', 'navigation.yml'), 'w') as ff:
    ff.writelines(lines)

# Copy over markdown files
print('Copying over textbook markdown files and modifying for Jekyll...')
markdown_files = glob(os.path.join(path_textbook, './chapters/**/*.md'), recursive=True)
for i_md in markdown_files:
    path_new = os.path.join(path_out, i_md.replace('chapters/', 'textbook/'))

    with open(i_md, 'r') as ff:
        lines = ff.readlines()
    
    # Create metadata
    insert_meta(lines, ['layout: single', 'sidebar:', '  nav: sidebar-textbook'])
       
    # Path for includes
    for ii, line in enumerate(lines):
        if 'notebooks-html' in line:
            # Update textbook jupyter notebook images
            new_line = '{% include ' + os.path.join('notebooks-html', line.split('notebooks-html/')[-1])
            lines[ii] = new_line.replace('"', '')
        elif '](/images' in line:
            # Update textbook images
            new_line = line.replace('](/images', ']({{ site.baseurl }}/images')
            lines[ii] = new_line
    
    if not os.path.isdir(os.path.dirname(path_new)):
        os.makedirs(os.path.dirname(path_new))
        
    with open(path_new, 'w') as ff:
        ff.writelines(lines)

# -- Copy over the notebooks-html pages --
print('Copying over generated HTML notebook pages...')
if os.path.exists(os.path.join(path_out, '_includes', 'notebooks-html')):
    sh.rmtree(os.path.join(path_out, '_includes', 'notebooks-html'))
sh.copytree(os.path.join(path_textbook, 'notebooks-html/'),
            os.path.join(path_out, '_includes', 'notebooks-html'))

# Update the HTML to use the site URL
print('Modifying generated notebook HTML for Jekyll...')
html_files = glob(os.path.join(path_out, '_includes', 'notebooks-html', '*.html'))
for i_html in html_files:
    with open(i_html, 'r') as ff:
        text = ff.read()
    newtext = text.replace('src="/notebooks-images', 'src="{{ site.baseurl }}/notebooks-images')
    newtext = newtext.replace('src="/images', 'src="{{ site.baseurl }}/images')

    with open(i_html, 'w') as ff:
        ff.write(newtext)
        
# Notebook Images
print('Copying generated notebook images...')
path_out_ntbk_img = os.path.join(path_out, 'notebooks-images')
if os.path.exists(path_out_ntbk_img):
    sh.rmtree(path_out_ntbk_img)
sh.copytree(os.path.join(path_textbook, 'notebooks-images'), path_out_ntbk_img)

# Images
print('Copying embedded markdown images...')
path_out_text_img = os.path.join(path_out, 'images')
if os.path.exists(path_out_text_img):
    sh.rmtree(path_out_text_img)
sh.copytree(os.path.join(path_textbook, 'images'), path_out_text_img)

# Replace interact links with jekyll-specific ones
print('Modifying interact links to work with Jekyll...')
for i_html in tqdm(html_files):
    with open(i_html, 'r') as ff:
        html_bs = bs(ff.read(), 'html5lib')
    
    # Find the interact link and skip if it's not there
    interact = html_bs.find_all('a', attrs={'class': 'interact-button'})
    if len(interact) == 0:
        continue
    interact = interact[0]

    # Grab the filepath, then replace the link with a jupyterhub jekyll link
    filepath = interact.attrs['href'].split('filepath=')[-1]
    new_link = create_hub_link(filepath)
    interact.attrs['href'] = new_link
    
    # Write the updated HTML
    with open(i_html, 'w') as ff:
        ff.write(str(html_bs))
    
print('Done!')
