import os, sys
import fnmatch
import argparse


def get_folder_structure(target_path):
    target_path = os.path.abspath(target_path)
    res = []
    for root, dir, files in os.walk(target_path):
        if '_source' in root:
            continue
        current_folder = os.path.abspath(root)[len(target_path) + 1:]
        if not current_folder:
            continue
        for item in fnmatch.filter(files, "*.h"):
            res.append(os.path.join(current_folder, item))

    return res


def _extract_structure_name(line):
    for i, char in enumerate(line):
        if char.isalpha():
            s_pos = i
            break
    else:
        print('Can not locate first alpha in [{}]'.format(line))
        sys.exit(1)

    e_pos = line.index(';')
    return line[s_pos: e_pos]


def convert(content):
    res = content[:]
    struct_start_index = [i for i, line in enumerate(content) if 'typedef struct {' in line]
    struct_end_index = [i for i, line in enumerate(content) if line.startswith('} ') and '_enum;' not in line]
    struct_index = [(i, j) for i, j in zip(struct_start_index, struct_end_index)]
    cur_struct_no = -1

    for i, org_line in enumerate(content):
        if 'typedef struct {' in org_line:
            cur_struct_no += 1
        if ':' in org_line and ';' in org_line:
            skip_from_pos = org_line.index(':')
            skip_to_pos = org_line.index(';')
            if skip_from_pos < skip_to_pos:
                res[i] = org_line[: skip_from_pos] + org_line[skip_to_pos:]
        if 'FLEXIBLE_ARRAY_SIZE' in org_line:
            struct_name = _extract_structure_name(content[struct_index[cur_struct_no][1]]).upper()
            # struct_name = content[struct_index[cur_struct_no][1]][2:-2].upper()
            substruct_name = org_line[org_line.index('N := ') + len('N := '): -1].lower()
            substruct_name = '_'.join([_ for _ in substruct_name.split(' ') if _ != ''])

            print('struct_name: ' + struct_name)
            print('substruct_name: ' + substruct_name)

            macro_str = '_'.join(['MAX', struct_name, substruct_name]).upper()
            res[i] = org_line[:org_line.index('FLEXIBLE_ARRAY_SIZE')] + \
                     macro_str + \
                     org_line[org_line.index('FLEXIBLE_ARRAY_SIZE') + len('FLEXIBLE_ARRAY_SIZE'):]
            print(org_line[:org_line.index('FLEXIBLE_ARRAY_SIZE')])
            print(macro_str)
            print(org_line[org_line.index('FLEXIBLE_ARRAY_SIZE') + len('FLEXIBLE_ARRAY_SIZE'):])

    return res


def convert_all_headers(input_top_folder, out_top_folder):
    input_top_folder = os.path.abspath(input_top_folder)
    out_top_folder = os.path.abspath(out_top_folder)
    fp_list = get_folder_structure(input_top_folder)

    for fp in fp_list:
        write_to_include_header_file('/'.join(fp.split(os.sep)), out_top_folder)
        with open(os.path.join(input_top_folder, fp), 'r') as fs:
            content = fs.readlines()
            conv_content = convert(content)

        output_dir = os.path.dirname(os.path.join(out_top_folder, fp))
        if not os.path.isdir(output_dir):
            os.makedirs(output_dir)
        with open(os.path.join(out_top_folder, fp), 'w') as fs:
            fs.writelines(conv_content)


def write_to_include_header_file(icd_path, output_fp):
    print('#include "{}"\n'.format(icd_path))
    with open(os.path.join(output_fp, 'icd_headers_ut.h'), "a") as outFile:
        outFile.write('#include "{}"\n'.format(icd_path))


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', action='store', dest='targetFolder', required=True,
                        help='Target path (the header file under the folder will be converted)')
    parser.add_argument('-o', action='store', dest='outputFolder',
                        help='Converted results will be stored under this path')
    parser.add_argument('-proj', action='store', dest='projectName', required=True)
    parser.add_argument('-flavor', action='store', dest='flavor', required=True)
    args = parser.parse_args()

    if not os.path.isdir(args.targetFolder):
        print('[ERROR] Target folder is not exist [{}] (ignored)'.format(args.targetFolder))
        sys.exit(1)
        # raise ValueError('Target folder is not exist [{}]'.format(targetFolder))
    else:
        input_top_folder = args.targetFolder

    if not args.outputFolder or os.path.isdir(args.outputFolder):
        PROJECT = args.projectName # os.environ['project_name']
        FLAVOR = args.flavor # os.environ['flavor']
        output_top_folder = os.path.join('build', PROJECT, FLAVOR, 'MoDIS', '_BUILD_XGEN', 'dhl', 'database_modis',
                                         'converted_icd_headers')
        if not os.path.exists(output_top_folder):
            os.makedirs(output_top_folder)
    else:
        output_top_folder = args.outputFolder

    convert_all_headers(input_top_folder, output_top_folder)
