#
# This file is part of the MicroPython project, http://micropython.org/
#
# The MIT License (MIT)
#
# Copyright (c) 2017 SummerGift <zhangyuan@rt-thread.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
import os
from sys import argv
import argparse
from gen_qstr import make_bytes

def qstr_end_idx(str):
    min = 255
    idx = str.find(')')
    if(idx > -1):
        min = idx
    idx = str.find(',')
    if idx > -1 and idx < min:
        min = idx
    idx = str.find(':')
    if idx > -1 and idx < min:
        min = idx
    idx = str.find('=')
    if idx > -1 and idx < min:
        min = idx
    idx = str.find(' ')
    if idx > -1 and idx < min:
        min = idx
    idx = str.find(';')
    if idx > -1 and idx < min:
        min = idx
    idx = str.find('<')
    if idx > -1 and idx < min:
        min = idx
    idx = str.find('}')
    if idx > -1 and idx < min:
        min = idx
    idx = str.find('{')
    if idx > -1 and idx < min:
        min = idx

    idx = str.find('.')
    if idx > -1 and idx < min:
        min = idx

    return min

def spec_charactor_filter(string):
    if ('#' in string):
        return False
    if ('/' in string):
        return False
    if ('*' in string):
        return False
    if ('//' in string):
        return False
    if ('(' in string):
        return False
    if (')' in string):
        return False
    if ('{' in string):
        return False
    if ('}' in string):
        return False
    if (' ' in string):
        return False
    if ('\\' in string):
        return False
    if ('}' in string):
        return False
    if ('-' in string):
        return False
    return True

def read_qstr(file,list):
    fd = open(file)
    try:
        for line in fd:
            idx = 0
            for i in range(5):
                idx = line.find('MP_QSTR_',idx)
                if (idx >= 0):
                    str = line[idx+len('MP_QSTR_'):-1]
                    lidx = qstr_end_idx(str)
                    qstr = str[0:lidx]
                    if spec_charactor_filter(qstr):
                        if qstr not in list:
                            list.append(qstr)
                    idx = idx +1
                else:

                    idx = line.find('Q(')
                    if idx ==0:
                        #print("**:",line+'  in  '+file)
                        str = line[idx+len('Q('):-1]
                        lidx = qstr_end_idx(str)
                        qstr = str[0:lidx]
                        if spec_charactor_filter(qstr):
                            if qstr not in list:
                                list.append(qstr)
                    
                    break


    except UnicodeDecodeError as e:
        print(e)
        print('in',file)

    fd.close()


def gen_qstr(path,hash_len=1):
    headerfile = './qstrdefs.generated.h'
    headerdef = '// This file was automatically generated by auto_generate_qstr.py' + '\n'+ '\n'
    headerdef = headerdef + '\n' + ' QDEF(MP_QSTRnull, (const byte*)"\\x00\\x00\\x00" "") '+ '\n'
    try:
        os.remove(headerfile)
    except WindowsError as e:
        print(e)
    qstr_list = []
    total = 0
    for (root, dirs, files) in os.walk(path):
        for file in files:

            if (file.split(".")[-1] == 'c'):
                read_qstr(root + '/' + file, qstr_list)

            if (file.split(".")[-1] == 'h'):
                read_qstr(root + '/' + file, qstr_list)

    outfd = open(headerfile, 'wt')
    outfd.writelines(headerdef)

    for qstr in qstr_list:
        out = make_bytes(1, hash_len, qstr)
        outfd.writelines(out + '\n');
        # print(out)

    outfd.close()
    print('Generate QString count:', len(qstr_list))

if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument('-d', '--dir', type=str, default='../',

                        help='txt file')
    args, unparsed = parser.parse_known_args()

    gen_qstr(args.dir)
