from lxml import etree
from copy import deepcopy


def insert_after(anchor_name: str, elem_name: str):
    file_path = "../decompiled/res/values/public.xml"
    parser = etree.XMLParser(remove_blank_text=True)
    tree = etree.parse(file_path, parser)
    root = tree.getroot()
    anchor = None
    types = {}

    for idx, elem in enumerate(root):
        assert elem.tag == "public"
        assert elem.keys() == ["type", "name", "id"]
        attrs = dict(zip(elem.keys(), elem.values()))
        if attrs["name"] == anchor_name:
            assert anchor == None
            anchor = (elem, attrs)
        types[attrs["type"]] = types.get(attrs["type"], []) + [int(attrs["id"], 16)]

    free_ids = set()
    group = types[anchor[1]["type"]]
    for i in range(min(group), max(group) + 1):
        if i not in group:
            free_ids.add(i)

    assert len(free_ids) > 0
    new_id = None
    for i in free_ids:
        if i > int(anchor[1]["id"], 16):
            new_id = i
            break
    if new_id == None:
        new_id = max(group) + 1

    for name, group in types.items():
        if name == anchor[1]["type"]:
            continue
        if new_id in group:
            new_id = max(group)

    new_elem = deepcopy(anchor[0])
    new_elem.set("id", new_id)
    new_elem.set("name", elem_name)
    anchor[0].addnext(new_elem)

    tree.write(file_path, pretty_print=True, xml_declaration=True, encoding="utf-8")
    return new_id
