import os
import sys
import traceback
import yaml
from bs4 import BeautifulSoup
from time import sleep
from shutil import copyfile

def foldersel(msg = ''):
    print(f'''SYNTAX:
    ls       : Lists files in current directory.
    lsf      : Lists folders in current directory.
    cd       : Change directory. Press enter, then type directory to change into.
    md/mkdir : Create directory. Press enter, then type directory to create.
    exit     : Exit and continue
    CTRL+C   : Exit and continue

{msg}''')
    while True:
        try:
            cmd = input(f'{os.getcwd()} $ ')
            if cmd == '':
                pass
            elif cmd == 'cd':
                try:
                    os.chdir(input('New directory: '))
                except FileNotFoundError:
                    print('''
Invalid folder!''')
            elif cmd == 'md':
                try:
                    newdir = input('New directory: ')
                    os.mkdir(newdir)
                    os.chdir(newdir)
                except FileExistsError:
                    print('''
Folder already exists!''')
            elif cmd == 'ls':
                files = []
                for item in os.listdir():
                    try:
                        os.chdir(item)
                        os.chdir('..')
                        files.append(f' - Folder : {item}')
                    except NotADirectoryError:
                        files.append(f' - File   : {item}')
                for item in files:
                    print(item)
            elif cmd == 'lsf':
                files = []
                for item in os.listdir():
                    try:
                        os.chdir(item)
                        os.chdir('..')
                        files.append(f' - Folder : {item}')
                    except NotADirectoryError:
                        pass
                for item in files:
                    print(item)
            elif cmd == 'exit':
                return os.getcwd()
            else:
                print('Invalid command!')
        except KeyboardInterrupt:
            sleep(1)
            return os.getcwd()

def trlparse(infile):
    infile = open(infile, 'r')
    infile_str = infile.read()
    infile.close()
    mode = 'key'
    key = ''
    attr = ''
    out = {}
    i = 1
    for item in list(infile_str):
        if mode == 'key':
            if item == '=':
                mode = 'attr'
            else:
                key += item
        elif mode == 'attr':
            if item == '''
''':
                out[key.replace('\n','')] = attr
                key = ''
                attr = ''
                mode = 'key'
            elif i == len(infile_str):
                attr += item
                out[key.replace('\n','')] = attr
                key = ''
                attr = ''
                mode = 'key'
            else:
                attr += item
        i += 1
    return out

infile = open('hdconfig.yml')
config = yaml.safe_load(infile)
infile.close()

diff_reverse = False

if not config['override']['enabled']:
    origin = foldersel('Please select the folder with the origin files.')
    print(f'Successfully selected {origin} as origin folder.')
    new = foldersel('Please select the folder with the new files.')
    print(f'Successfully selected {new} as new folder.')
    html_origin = foldersel('Please select the folder with the origin HTML files.')
    print(f'Successfully selected {html_origin} as origin HTML folder.')
    html_new = foldersel('Please select the folder for the new HTML files to be placed.')
    print(f'Successfully selected {html_new} as new HTML folder.')
    diff = input('Please type title ending difference from origin files to new files: ')
    html_diff = input('Please type HTML file ending difference from origin files to new files: ')
    trl_diff = input('Please type FRQ/TRL file ending difference from origin files to new files: ')
else:
    origin = config['override']['origin']
    new = config['override']['new']
    html_origin = config['override']['html_origin']
    html_new = config['override']['html_new']
    diff = config['override']['diff']
    html_diff = config['override']['html_diff']
    trl_diff = config['override']['trl_diff']

try:
    if list(diff)[0] == '-':
        diff_reverse = True
        diff = diff.replace('-', '')
        html_diff = html_diff.replace('-', '')
        trl_diff = trl_diff.replace('-', '')
except IndexError:
    pass
# Get list of TRL files
os.chdir(new)
debug__cwd = new
trlfiles = []
for item in os.listdir():
    if '.trl' in item and not '.bak' in item:
        trlfiles.append(item)

errors = []
errors_detailed = []
for item in trlfiles:
    try:
        stop = False
        os.chdir(new)
        debug__cwd = new
        try:
            temp = trlparse(item)['html']
        except KeyError:
            # Get source program filename
            file = item
            if diff_reverse:
                srcname = file.replace('.trl', '') + trl_diff
            else:
                srcname = file.replace('.trl', '').replace(trl_diff, '')

            # Find source HTML file and copy to destination
            os.chdir(origin)
            debug__cwd = origin
            htmlname = trlparse(f'{srcname}.trl')['html'].split('/', 100)[-1]
            if diff_reverse:
                htmlname_new = f'''{htmlname.replace('.html', '')}.html'''.replace(html_diff, '')
            else:
                htmlname_new = f'''{htmlname.replace('.html', '')}{html_diff}.html'''
            copyfile(f'{html_origin}/{htmlname}', f'{html_new}/{htmlname_new}')

            # Link with destination TRL file
            os.chdir(new)
            debug__cwd = new
            infile = open(file, 'r')
            srctext = infile.read()
            infile.close()
            outfile = open(file, 'w')
            outfile.write(f'''{srctext}
html={html_new.split('html/', 1)[1]}/{htmlname_new}''')

            # Fix new HTML file
            os.chdir(html_new)
            debug__cwd = html_new
            css_prefix = ''
            debug__html_new_replace = html_new.replace(html_origin.split('TrueRife Frequencies/', 1)[0], '').replace('TrueRife Frequencies/', '')
            for item in debug__html_new_replace:
                if item == '/':
                    css_prefix += '../'
            infile = open(htmlname_new, 'r')
            srctext = infile.read()
            soup = BeautifulSoup(srctext, features='html.parser')
            infile.close()
            outfile = open(htmlname_new, 'w')
            debug__soup_h1_text_replace = soup.h1.text
            debug__soup_h1_text_replace = debug__soup_h1_text_replace.replace(diff, '')
            if diff_reverse:
                outfile.write(srctext.replace(soup.link['href'], f'{css_prefix}css/main.css').replace(str(soup.h1), f'<h1>{debug__soup_h1_text_replace}</h1>'))
            else:
                outfile.write(srctext.replace(soup.link['href'], f'{css_prefix}css/main.css').replace(str(soup.h1), f'<h1>{soup.h1.text}{diff}</h1>'))
            outfile.close()
    except:
        errors.append(srcname)
        errors_detailed.append([srcname, sys.exc_info(), globals()])
if len(errors) > 0:
    print('Errors occured while processing these programs:')
    for item in errors:
        print(f' - {item}')

if input('Enter error viewer? [y/N] ').lower() == 'y':
    esel = '#'
    print('''HELP:
    lse           : List exception
    sel <error #> : Select exception
    disp          : Display selected exception
    vars          : Show all variables
    exit          : Exit
    CTRL+C        : Exit''')
    while True:
        try:
            cmd = input(f'Error Viewer ({esel})> ').split(' ',100)
            if cmd[0] == 'lse':
                for item in errors_detailed:
                    print(f'{errors_detailed.index(item)} : {item[0]}')
                print(f'{len(errors_detailed)} total errors')
            elif cmd[0] == 'sel':
                esel = int(cmd[1])
            elif cmd[0] == 'disp':
                if esel != '#' and type(esel) == int:
                    print()
                    print('Variables:')
                    for item in list(errors_detailed[esel][2].keys()):
                        if item != 'errors_detailed':
                            print(f'    {item} : {errors_detailed[esel][2][item]}')
                    print()
                    print(f'{errors_detailed[esel][1][0].__name__} in {errors_detailed[esel][0]}:')
                    traceback.print_tb(errors_detailed[esel][1][2])
                    print(f'{errors_detailed[esel][1][0].__name__}: {errors_detailed[esel][1][1]}')
                    print()
            elif cmd[0] == 'vars':
                print()
                print('Variables:')
                for item in list(globals().keys()):
                    if item != 'errors_detailed':
                        print(f'    {item} : {globals()[item]}')
                print()
            elif cmd[0] == 'exit':
                break
        except KeyboardInterrupt:
            break
        except (IndexError, ValueError) as e:
            print('Invalid command syntax!')