import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))

from verilog_framework.core.lexer import VerilogLexer
from verilog_framework.core.parser import VerilogParser
from verilog_framework.core.ast_nodes import Module, Port, Assign, Always


def test_parser_simple_module():
    code = """
    module simple_mod();
    endmodule
    """
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    parser = VerilogParser(tokens)
    ast = parser.parse()
    
    assert isinstance(ast, Module)
    assert ast.name == "simple_mod"
    assert len(ast.port_list) == 0
    print("✓ test_parser_simple_module passed")


def test_parser_module_with_ports():
    code = """
    module adder(
        input [3:0] a,
        input [3:0] b,
        output [4:0] result
    );
    endmodule
    """
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    parser = VerilogParser(tokens)
    ast = parser.parse()
    
    assert ast.name == "adder"
    assert len(ast.port_list) == 3
    assert ast.port_list[0].name == "a"
    assert ast.port_list[0].direction == "input"
    assert ast.port_list[1].name == "b"
    assert ast.port_list[2].name == "result"
    assert ast.port_list[2].direction == "output"
    print("✓ test_parser_module_with_ports passed")


def test_parser_wire_declaration():
    code = """
    module test();
        wire [7:0] sig;
    endmodule
    """
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    parser = VerilogParser(tokens)
    ast = parser.parse()
    
    assert len(ast.declarations) == 1
    assert ast.declarations[0].name == "sig"
    print("✓ test_parser_wire_declaration passed")


def test_parser_assign_statement():
    code = """
    module test();
        assign a = 1;
    endmodule
    """
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    parser = VerilogParser(tokens)
    ast = parser.parse()
    
    assigns = [s for s in ast.statements if isinstance(s, Assign)]
    assert len(assigns) >= 1
    print("✓ test_parser_assign_statement passed")


def test_parser_always_block():
    code = """
    module test();
        always @(posedge clk) begin
            out <= 1;
        end
    endmodule
    """
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    parser = VerilogParser(tokens)
    ast = parser.parse()
    
    always_blocks = [s for s in ast.statements if isinstance(s, Always)]
    assert len(always_blocks) >= 1
    print("✓ test_parser_always_block passed")


def test_parser_arithmetic_expression():
    code = """
    module test();
        wire result;
        assign result = a + b;
    endmodule
    """
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    parser = VerilogParser(tokens)
    ast = parser.parse()
    
    assigns = [s for s in ast.statements if isinstance(s, Assign)]
    assert len(assigns) >= 1
    print("✓ test_parser_arithmetic_expression passed")


def test_parser_complex_module():
    code = """
    module multiplexer(
        input a,
        input b,
        input select,
        output out
    );
        assign out = a;
        assign out = b;
    endmodule
    """
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    parser = VerilogParser(tokens)
    ast = parser.parse()
    
    assert ast.name == "multiplexer"
    assert len(ast.port_list) == 4
    print("✓ test_parser_complex_module passed")


def test_parser_reg_declaration():
    code = """
    module test();
        reg [15:0] counter;
    endmodule
    """
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    parser = VerilogParser(tokens)
    ast = parser.parse()
    
    assert len(ast.declarations) == 1
    assert ast.declarations[0].name == "counter"
    print("✓ test_parser_reg_declaration passed")


if __name__ == "__main__":
    test_parser_simple_module()
    test_parser_module_with_ports()
    test_parser_wire_declaration()
    test_parser_assign_statement()
    test_parser_always_block()
    test_parser_arithmetic_expression()
    test_parser_complex_module()
    test_parser_reg_declaration()
    print("\nAll parser tests passed! ✓")
