import re

class DaxParser:
    """Class to parse DAX expressions and build dependency graphs."""
    
    def __init__(self):
        """Initialize the DAX parser."""
        # Regular expression to match measure references in DAX
        # This is a simplified pattern and may need refinement for complex DAX
        self.measure_ref_pattern = r'\[([^\]]+)\]'
    
    def extract_measure_references(self, dax_expression, all_measure_names):
        """
        Extract references to other measures from a DAX expression.
        
        Args:
            dax_expression (str): The DAX expression to parse
            all_measure_names (list): List of all measure names in the model
            
        Returns:
            list: Names of measures referenced in the expression
        """
        if not dax_expression:
            return []
        
        # Find all potential measure references (anything in square brackets)
        potential_refs = re.findall(self.measure_ref_pattern, dax_expression)
        
        # Filter to only include actual measure names
        # This helps avoid false positives like column references
        measure_refs = [ref for ref in potential_refs if ref in all_measure_names]
        
        return list(set(measure_refs))  # Remove duplicates
    
    def build_call_graph(self, measures):
        """
        Build a call graph of measure dependencies.
        
        Args:
            measures (list): List of measure dictionaries with 'name' and 'expression' keys
            
        Returns:
            dict: A graph representation with nodes and links
        """
        # Extract all measure names
        all_measure_names = [measure['name'] for measure in measures]
        
        # Create nodes for the graph
        nodes = [{'id': measure['name'], 'expression': measure['expression']} for measure in measures]
        
        # Create links (dependencies) for the graph
        links = []
        for measure in measures:
            source = measure['name']
            expression = measure['expression']
            
            # Find references to other measures in this expression
            references = self.extract_measure_references(expression, all_measure_names)
            
            # Add links for each reference
            for target in references:
                links.append({
                    'source': source,
                    'target': target
                })
        
        return {
            'nodes': nodes,
            'links': links
        }