"""
Setup the geowatch package mirror

python ~/code/watch/dev/maintain/mirror_package_geowatch.py

SeeAlso:
    ~/code/watch/dev/maintain/port_to_geowatch.py
"""

import networkx as nx
import ubelt as ub


def main():

    main_name = 'geowatch'
    mirror_name = 'watch'

    module = ub.import_module_from_name(main_name)
    module_dpath = ub.Path(module.__file__).parent
    do_mirror(module_dpath, mirror_name)


def do_mirror(module_dpath, mirror_name):

    repo_dpath = module_dpath.parent

    g = nx.DiGraph()
    g.add_node(module_dpath, label=module_dpath.name, type='dir')

    for root, dnames, fnames in module_dpath.walk():
        # dnames[:] = [d for d in dnames if not dname_block_pattern.match(d)]
        if '__init__.py' not in fnames:
            dnames.clear()
            continue

        g.add_node(root, label=root.name, type='dir')
        if root != module_dpath:
            g.add_edge(root.parent, root)

        # for d in dnames:
        #     dpath = root / d
        #     g.add_node(dpath, label=dpath.name)
        #     g.add_edge(root, dpath)

        for f in fnames:
            if f.endswith('.py'):
                fpath = root / f
                g.add_node(fpath, label=fpath.name, type='file')
                g.add_edge(root, fpath)

    for p in list(g.nodes):
        node_data = g.nodes[p]
        ntype = node_data.get('type', None)
        if ntype == 'dir':
            node_data['label'] = ub.color_text(node_data['label'], 'blue')
        elif ntype == 'file':
            node_data['label'] = ub.color_text(node_data['label'], 'green')

    nx.write_network_text(g)

    new_modpath = repo_dpath / mirror_name

    from rich.prompt import Confirm
    if new_modpath.exists():
        if Confirm.ask(f'Delete {new_modpath}?'):
            new_modpath.delete()

    def extract_main_body(old_text):
        import parso
        import ast
        module = parso.parse(old_text)
        for child in module.children:
            if child.type == 'if_stmt':
                if_stmt = child
                if if_stmt.children[0].value == 'if':
                    condition = if_stmt.children[1]
                    if condition.type == 'comparison':
                        is_cannonical_main_block = (
                            condition.children[0].value == '__name__' and
                            condition.children[1].value == '==' and
                            condition.children[2].type == 'string' and
                            ast.literal_eval(condition.children[2].value) == '__main__'
                        )
                        if is_cannonical_main_block:
                            if_body = if_stmt.children[3]

                            import copy
                            if_body = copy.deepcopy(if_body)
                            to_remove = []
                            # Remove doctest
                            for idx, part in enumerate(if_body.children):
                                if part.type == 'simple_stmt':
                                    if len(part.children) == 2:
                                        if part.children[0].type == 'string':
                                            to_remove += [idx]

                            for idx in sorted(to_remove)[::-1]:
                                del if_body.children[idx]

                            global_names = []
                            for idx, part in enumerate(if_body.children):
                                if part.type == 'simple_stmt':
                                    if part.children[0].type == 'atom_expr':
                                        if part.children[0].children[0].type == 'name':
                                            global_names += [part.children[0].children[0].value]

                            main_body_code = (if_body.get_code())
                            return main_body_code, global_names
        return None, []

    for old_fpath, node_data in ub.ProgIter(g.nodes(data=True), desc='mirroring'):
        if node_data['type'] == 'file':
            relpath = old_fpath.relative_to(module_dpath)
            new_fpath = new_modpath / relpath
            new_fpath.parent.ensuredir()
            modname = ub.modpath_to_modname(old_fpath)

            old_text = old_fpath.read_text()
            main_body_code, global_names = extract_main_body(old_text)

            # if new_fpath.name == '__main__.py':
            #     import xdev
            #     xdev.embed()
            #     new_fpath.write_text(ub.codeblock(
            #         f'''
            #         from {modname} import main
            #         if __name__ == '__main__':
            #             main()
            #         '''))
            # else:
            parts = []

            parts += [ub.codeblock(
                '''
                # Autogenerated via:
                # python ~/code/watch/dev/maintain/mirror_package_geowatch.py
                ''')]

            if global_names:
                parts += [f'from {modname} import ' + ', '.join(global_names)]

            parts += ['\n\n' + ub.codeblock(
                f'''
                def __getattr__(key):
                    import {modname} as mirror
                    return getattr(mirror, key)


                def __dir__():
                    import {modname} as mirror
                    return dir(mirror)
                ''')]

            if main_body_code:
                parts += ['\n\n' + ub.codeblock(
                    '''
                    if __name__ == '__main__':
                    ''') + main_body_code]

            new_text = '\n'.join(parts)
            new_fpath.write_text(new_text)

    print('Dont forget to:')
    print(f'git add {new_modpath}')


if __name__ == '__main__':
    """
    CommandLine:
        python ~/code/geowatch/dev/maintain/mirror_package_geowatch.py

    python -c "import geowatch; print('geowatch.__version__ = ' + str(geowatch.__version__))"
    python -c "import geowatch; print('geowatch.__name__ = ' + str(geowatch.__name__))"

    python -m geowatch
    """
    main()
