import psutil
import gc
from pympler import summary
from pympler import muppy
from pympler import refbrowser
import referrers
from fastapi import Request
from AvenirCommon.Logger import get_pt_log_level, set_pt_log_level, LogLevelCodes

     
global mem_base
mem_base = None

def setup_version_services(app):
    @app.get("/", tags=['Global'])
    def root():
        return f'Welcome to {app.title}. Version {app.version}' 


    @app.get("/Version", tags=['Global'])
    def Version():
        return app.version

    @app.post("/GetVersion", tags=['Global'])
    def GetVersion():
        return app.version
    
    @app.get("/SystemStats", tags=['Global'])
    def SystemStats():
        gc.collect()
        
        return {
            'cpuPercent':psutil.cpu_percent(), 
            'percentMemoryAvailable': 100*(psutil.virtual_memory().available / psutil.virtual_memory().total),
            'virtualMemory':psutil.virtual_memory()._asdict()
        }
    
    @app.get("/SetLogLevel/{level}", tags=["Global"])
    @app.post("/SetLogLevel/{level}", tags=["Global"])
    def SetLogLevel(level:LogLevelCodes, request:Request):
        return set_pt_log_level(level)
        
    @app.get("/GetLogLevel", tags=["Global"])
    @app.post("/GetLogLevel", tags=["Global"])
    def GetLogLevel(request:Request):
        return get_pt_log_level()
    
    @app.get("/ResetMemoryTrap", tags=['Global'])
    def ResetMemoryTrap():
        gc.collect()
        all_objects = muppy.get_objects()
        global mem_base
        mem_base = summary.summarize(all_objects)
        pass
    
    @app.get("/MemoryTrap", tags=['Global'])
    def MemoryTest():
        gc.collect()
        all_objects = muppy.get_objects()

        mem_trap = summary.summarize(all_objects)
        global old_summary
        diff_sum = summary.get_diff(mem_base, mem_trap) if mem_base else []
        diff_list = [rec for rec in diff_sum if (rec[1]+rec[2])>0]
        def output_function(o):
             return str(type(o))
        
        cb = refbrowser.ConsoleBrowser(mem_trap, maxdepth=2, str_func=output_function)
        # summary.print_(sum1)  
        new_diff_list = []
        o1_ids = {id(obj) for obj in mem_base}
        o2_ids = {id(obj): obj for obj in mem_trap}
        diff = [obj for obj_id, obj in o2_ids.items() if obj_id not in o1_ids]
        for obj in diff_list:
            ref = referrers.get_referrer_graph(
                    obj,
                    exclude_object_ids=[id(mem_base), id(mem_trap), id(diff_list), id(o2_ids)]
                )
            
            print(ref)
            new_diff_list.append(ref)
            
        
        return {
            'cpuPercent':psutil.cpu_percent(), 
            'percentMemoryAvailable': 100*(psutil.virtual_memory().available / psutil.virtual_memory().total),
            'virtualMemory':psutil.virtual_memory()._asdict(),
            'muppyLen': len(diff_list),
            'muppy':diff_list 
        }