class PawserNode:
    def __init__(self, typeName, attrs=None):
        self.type = typeName
        self.attrs = attrs or {}
        self.children = []

class PawserTextNode:
    def __init__(self, content):
        self.type = "text"
        self.content = content
        self.children = []

def parseGeneralTag(line, lineNo):
    """Parse general tags (h1, h2, h3, ol, p) - all handled the same way"""
    parts = line[1:].split(" ", 1)
    tag = parts[0]
    rest = parts[1] if len(parts) > 1 else None
    
    node = PawserNode(tag)
    if rest:
        node.children.append(PawserTextNode(rest))
    return node

def parseSpecialTag_li(line, lineNo):
    #if it finds a #li node it just returns "li" because there is no need for text finding
    node = PawserNode("li")
    return node

def parseSpecialTag_it(line, lineNo):
    """Parse 'it' tag - this is a list item with text content"""
    # Remove the # to get "#it buy eggs" -> "it buy eggs"
    lineWithoutHash = line[1:]
    
    # Split into tag and content: "it buy eggs" -> ["it", "buy eggs"]
    parts = lineWithoutHash.split(" ", 1)
    tagName = parts[0]  # "it"
    textContent = parts[1] if len(parts) > 1 else None  # "buy eggs" or None
    
    # Create the item node
    node = PawserNode("it")
    
    # Add text as a child if there is any
    if textContent:
        node.children.append(PawserTextNode(textContent))
    
    return node

def parsePawml(filePath):
    with open(filePath, "r", encoding="utf-8") as f:
        lines = [line.rstrip("\n") for line in f]
    
    # Validate first line
    for line in lines:
        if line.strip():
            firstLine = line.strip()
            break
    else:
        raise ValueError("Error: File is empty")
    
    if firstLine != "#pawml":
        raise ValueError("Error: File must start with #pawml")
    
    # Validate last line
    for line in reversed(lines):
        if line.strip():
            lastLine = line.strip()
            break
    else:
        raise ValueError("Error: File is empty")
    
    if lastLine != "#pawml":
        raise ValueError("Error: File must end with #pawml")
    
    root = PawserNode("pawml")
    stack = [(root, -1)]
    
    generalTags = ["h1", "h2", "h3", "ol", "p"]
    specialTags = {
        "li": parseSpecialTag_li,
        "it": parseSpecialTag_it
    }
    
    for lineNo, line in enumerate(lines[1:-1], start=2):
        if not line.strip():
            continue
        
        # Calculate indentation
        indent = 0
        while line.startswith("\t"):
            indent += 1
            line = line[1:]
        
        # Stop if we hit the closing #pawml early
        if line == "#pawml":
            break
        
        # Handle metadata
        if line.startswith("#mdata"):
            try:
                parts = line[6:].strip().split("=", 1)
                if len(parts) != 2:
                    raise ValueError
                key = parts[0].strip()
                value = parts[1].strip().strip('"')
                if not value:
                    raise ValueError
                node = PawserNode("mdata")
                node.children.append(PawserNode(key))
                node.children[-1].children.append(PawserTextNode(value))
            except:
                raise ValueError(f"Error: Invalid mdata on line {lineNo}: '{line}'")
        
        # Handle tags
        elif line.startswith("#"):
            parts = line[1:].split(" ", 1)
            tag = parts[0]
            
            # Check if it's a general tag
            if tag in generalTags:
                node = parseGeneralTag(line, lineNo)
            
            # Check if it's a special tag
            elif tag in specialTags:
                parseFunc = specialTags[tag]
                node = parseFunc(line, lineNo)
            
            # Unknown tag
            else:
                raise ValueError(f"Error: Unknown tag '{tag}' on line {lineNo}")
        
        # Plain text
        else:
            node = PawserTextNode(line)
        
        # Handle stack and parent-child relationships
        while stack and stack[-1][1] >= indent:
            stack.pop()
        
        if not stack:
            raise ValueError(f"Error: Invalid indentation on line {lineNo}") # im so tired of coding this bullshit
        
        parent = stack[-1][0]
        parent.children.append(node)
        stack.append((node, indent))
    
    return root

def printTree(node, indent=0):
    space = "    " * indent
    if node.type == "text":
        print(space + f'"{node.content}"')
        return
    attrs = f" {node.attrs}" if node.attrs else ""
    print(space + node.type + attrs)
    for child in node.children:
        printTree(child, indent + 1)

def pawml2domtree(filePath):
    try:
        return parsePawml(filePath)
    except Exception as e:
        print(e)
        return None