import os
import os.path
import click
import textwrap
import fnmatch

# mime dictionary depending on file extention
mime_type = { 'html': 'TEXT_HTML',
              'htm' : 'TEXT_HTML',
              'xml' : 'TEXT_XML',
              'css' : 'TEXT_CSS',
              'png' : 'IMAGE_PNG',
              'gif' : 'IMAGE_GIF',
              'js'  : 'JAVASCRIPT',
              'ico' : 'IMAGE_MICROSOFT' }

HEADER_TEMPLATE ="""\
/* Auto-generated by pyresource. Do not edit this file. */
const uint8_t {varname}_data[{len}] = {{
{data_hex}
}};

const HTTPResource {varname}({varname}_data, {len});
"""

RESOURCE_H_TEMPLATE = """\
#ifndef _{guard_name}_H_
#define _{guard_name}_H_

/* Auto-generated by pyresource. Do not edit this file. */

#include "http_common.h"
{includes}

/* HTTPPage collection from generated headers

{http_pages}

*/

#endif /* ifndef _{guard_name}_H_ */
"""

@click.command(short_help='Converts resource files into C headers for HTTP server.')
@click.argument('dir', type=click.Path(True, False, True), nargs=1, required=True)
def pyresource(dir):
    """Adafruit Python HTTP Resource Tool

    This tool recursively converts the folder contents into HTTP server
    resources in a C header format. These headers can then be imported into
    WICED Feather HTTP server sketches.

    Example of recursively converting the contents of the 'resources' folder:

      $ python pyresource.py resources
    """
    includes = ''
    http_pages = ''

    print("Looking for files in '%s'" % (dir))
    matches = []
    for root, dirnames, filenames in os.walk(dir):
        for f in fnmatch.filter(filenames, '*'): # Optional filter
            pf = os.path.join(root, f); # f = path + filename
            # Make sure this isn't the python script or a hidden file/folder
            if (f != os.path.basename(__file__)) and not (f.startswith(".")):
                # varname is name of C variable, also used as basename for header file
                # dir prefix is drop, "/" is replaced by _dir_ and "." or "-" is replace by "_"
                # e.g resources/css/style.cs ---> css_dir_style_cs.h (resources is parameter to pyresource.py)
                varname = pf[len(dir)+1:]
                varname = varname.replace(os.sep, '_dir_')
                varname = varname.replace('.', '_')
                varname = varname.replace('-', '_')
                # add undercore if file name start with a number
                if varname[1].isdigit():
                    varname = '_' + varname
                params = {}
                params['varname'] = varname
                with open(pf, "rb") as fin:
                    data = fin.read()
                    data_hex = ', '.join(['0x{0:02X}'.format(ord(x)) for x in data])
                    # Set data to hex string (wrapped nicely on 80 character boundary).
                    data_hex = textwrap.fill(data_hex, width=80, break_long_words=False,
                                             break_on_hyphens=False, initial_indent='  ', subsequent_indent='  ')
                    params['len'] = len(data)
                    params['data_hex'] = data_hex
                with open(varname + '.h', "w") as fout:
                    fout.write(HEADER_TEMPLATE.format(**params))
                includes += '#include "' + varname + '.h"\n'
                ext = os.path.splitext(f)[1][1:].lower()
                http_pages += 'HTTPPage("/' + pf[len(dir)+1:].replace(os.sep, '/') + '", HTTP_MIME_' + mime_type.get(ext, 'UNKNOWN') + ', &' + varname + '),\n'
                # Debug output
                print("Converted '%s' to '%s'" % (pf, varname + '.h'))
            else:
                print("Ignoring  '%s'" % (pf))

    with open('resources.h', "w") as fout:
        params = {}
        params['guard_name'] = 'RESOURCE'
        params['includes'] = includes
        params['http_pages'] = http_pages
        fout.write(RESOURCE_H_TEMPLATE.format(**params))
        print("Wrote resource index to 'resources.h'")

if __name__ == '__main__':
    pyresource()
