import os 
from pathlib import Path

def recursiveSearchForDockerComposeFiles(watchFolder: Path):
    dockerComposeList = []
    for root, _, files in os.walk(watchFolder):
        for file in files:
            if file == "docker-compose.yaml":
                dockerComposeList.append(Path(root) / file)
    return dockerComposeList

def readDockerComposeFile(dockerComposeFile: Path) -> str:
    with open(dockerComposeFile, "r") as file:
        data = file.read()
    return data

def getTraefikLabelsFromDockerComposeFile(dockerComposeFile: str):
    traefikLabels = []
    # Find all traefik labels
    d = readDockerComposeFile(dockerComposeFile)
    lines = d.split("\n")
    for line in lines:
        if "traefik." in line:
            traefikLabels.append(line)
    return traefikLabels

def parseTraefikLabels(traefikLabels: list):
    s = {
        "routers": [],
        "services": [],
    }
    for label in traefikLabels:
        if "traefik.http.routers" in label:
            routerName = label.split(".")[3]
            s["routers"].append(routerName)
        elif "traefik.http.services" in label:
            serviceName = label.split(".")[3]
            s["services"].append(serviceName)
    # Make unique
    s["routers"] = list(set(s["routers"]))
    s["services"] = list(set(s["services"]))
    return s

def checkLabelUnique(labels: dict) -> bool:
    routerNames = []
    wrong = False
    for project in labels:
        for router in labels[project]["routers"]:
            if router in routerNames:
                if not wrong:
                    print("\n\n Seems like some routers are not unique šŸ–\n")
                print(f"šŸ”“ ERROR : Router *{router}* is not unique")
                wrong = True
                for project2 in labels:
                    if router in labels[project2]["routers"]:
                        print(f"\t{project} and {project2}")
            routerNames.append(router)
    return wrong
def beautifulDisplayLabels(labels: dict, projectName: str):
    print(f"\n======\nšŸ§° Project: {projectName}")
    print("šŸŽ›ļø  Routers:")
    for router in labels["routers"]:
        print(f"\t{router}")
    if len(labels["services"]) != 0:
        print("šŸŽ›ļø  Services:")
        for service in labels["services"]:
            print(f"\t{service}")
            
def main(watchFolder: str):
    # For each folder, read docker-compose.yaml and look for traefik labels
    dockerComposeList = recursiveSearchForDockerComposeFiles(watchFolder)
    labels = {}
    for dockerComposeFile in dockerComposeList:
        traefikLabels = getTraefikLabelsFromDockerComposeFile(dockerComposeFile)
        if len(traefikLabels) == 0:
            #print(f"No traefik labels found in {dockerComposeFile}")
            continue
        parsedTraefikLabels = parseTraefikLabels(traefikLabels)
        projectName = dockerComposeFile.parent.name
        labels[projectName] = parsedTraefikLabels
        beautifulDisplayLabels(parsedTraefikLabels, projectName)
    # Check if all routers are unique
    wrong = checkLabelUnique(labels)
    
    if wrong:
        exit(1)
    else:
        print("\n\nāœ… All routers are unique\n\n")
        exit(0)

if __name__ == "__main__":
    print("Traefik label watcher CI/CD")
    # Read folder from env
    watchFolder = os.getenv("WATCH_FOLDER")
    if watchFolder == None:
        watchFolder = "."
        
    watchFolder = Path(watchFolder)
    
    main(watchFolder)