import sys
from pathlib import Path

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

from verilog_framework.core.lexer import VerilogLexer, TokenType


def test_lexer_keywords():
    code = "module endmodule input output wire reg"
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    
    keywords = [t for t in tokens if t.type == TokenType.KEYWORD]
    assert len(keywords) == 6
    assert all(t.value in ['module', 'endmodule', 'input', 'output', 'wire', 'reg'] for t in keywords)
    print("✓ test_lexer_keywords passed")


def test_lexer_identifiers():
    code = "sig1 signal_2 _internal $var"
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    
    identifiers = [t for t in tokens if t.type == TokenType.IDENTIFIER]
    assert len(identifiers) == 4
    print("✓ test_lexer_identifiers passed")


def test_lexer_numbers():
    code = "42 1010 65535 0"
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    
    numbers = [t for t in tokens if t.type == TokenType.NUMBER]
    assert len(numbers) >= 3
    print("✓ test_lexer_numbers passed")


def test_lexer_operators():
    code = "+ - * / & | ^ << >> == != <= >="
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    
    operators = [t for t in tokens if t.type == TokenType.OPERATOR]
    assert len(operators) >= 10
    print("✓ test_lexer_operators passed")


def test_lexer_delimiters():
    code = "( ) [ ] { } , ; . ="
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    
    delimiters = [t for t in tokens if t.type == TokenType.DELIMITER]
    assert len(delimiters) >= 9
    print("✓ test_lexer_delimiters passed")


def test_lexer_line_tracking():
    code = "signal1\nsignal2\nsignal3"
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    
    identifiers = [t for t in tokens if t.type == TokenType.IDENTIFIER]
    assert identifiers[0].line == 1
    assert identifiers[1].line == 2
    assert identifiers[2].line == 3
    print("✓ test_lexer_line_tracking passed")


def test_lexer_complex_expression():
    code = "assign result = (a + b) & (c | d);"
    lexer = VerilogLexer(code)
    tokens = lexer.tokenize()
    
    token_values = [t.value for t in tokens if t.type != TokenType.EOF]
    assert 'assign' in token_values
    assert 'result' in token_values
    assert '+' in token_values
    assert '&' in token_values
    print("✓ test_lexer_complex_expression passed")


if __name__ == "__main__":
    test_lexer_keywords()
    test_lexer_identifiers()
    test_lexer_numbers()
    test_lexer_operators()
    test_lexer_delimiters()
    test_lexer_line_tracking()
    test_lexer_complex_expression()
    print("\nAll lexer tests passed! ✓")
