package cparser_tests;

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import java.lang.String;

import cparser.Parser;
import cparser.Tokenizer;
import cparser.AST;
import cparser.Log;

import java.util.List;

public class ParserTests {
  private Parser parser;
  private Tokenizer.TokenSet tokenSet;
  private Log testLog;

  @Before
  public void setUp() {
    testLog = new Log() {
      @Override
      public void log(String msg) {
        System.out.println(msg);
      }
    };
  }

  @Test
  public void testParseVariableDecl() {
    String[] testCases = {
        "byte RVar1;",
        "tdstLastErrorInfo *pdVar2;",
        "undefined4 *puVar2;",
        "CHAR pathToUbi_ini[260];",
        "undefined& DAT_005a9ed4;",
        "char(&s_Identifier_005b6420)[16];",
        "void (*fnType)(int j, char, bool);",
        "void** (*fnType)(int j, char, bool);"
    };

    for (String code : testCases) {
      tokenSet = new Tokenizer(code).parse();
      parser = new Parser(tokenSet, testLog);
      parser.parse();

      List<AST.VariableDeclaration> declarations = parser.getVariableDeclarations();
      assertEquals("Failed for case: " + code, 1, declarations.size());
      AST.VariableDeclaration decl = declarations.get(0);
      assertNotNull(decl);
      System.out.println("Parsed: " + code);
      System.out.println("  Type: " + decl.type);
      System.out.println("  Identifier: " + decl.identifier);
      System.out.println("  Is Pointer: " + decl.isPointer);
      System.out.println("  Is Reference: " + decl.isReference);
      System.out.println("  Is Array: " + decl.isArray);
      System.out.println("  Array Size: " + decl.arraySize);
      System.out.println("  Is Function: " + decl.isFunction);
      System.out.println();
    }
  }

  /*
   * @Test
   * public void testParseFunctionDeclaration() {
   * String code = "void foo(int a, int b);";
   * tokenSet = new Tokenizer(code).parse();
   * parser = new Parser(tokenSet, testLog);
   * parser.parse();
   * 
   * List<Parser.Function> functions = parser.getFunctions();
   * assertEquals(1, functions.size());
   * assertEquals("foo", functions.get(0).name);
   * assertFalse(functions.get(0).isDefinition);
   * }
   * 
   * @Test
   * public void testParseFunctionDefinition() {
   * String code = "int bar(int x) { return x + 1; }";
   * tokenSet = new Tokenizer(code).parse();
   * parser = new Parser(tokenSet, testLog);
   * parser.parse();
   * 
   * List<Parser.Function> functions = parser.getFunctions();
   * assertEquals(1, functions.size());
   * assertEquals("bar", functions.get(0).name);
   * assertTrue(functions.get(0).isDefinition);
   * }
   * 
   * @Test
   * public void testParseFunctionCall() {
   * String code = "result = calculate(5, 10);";
   * tokenSet = new Tokenizer(code).parse();
   * parser = new Parser(tokenSet, testLog);
   * parser.parse();
   * 
   * List<Parser.FunctionCall> functionCalls = parser.getFunctionCalls();
   * assertEquals(1, functionCalls.size());
   * assertEquals("calculate", functionCalls.get(0).name);
   * }
   * 
   * @Test
   * public void testParsePreprocessorDirective() {
   * String code = "#include <stdio.h>\nint main() { return 0; }";
   * tokenSet = new Tokenizer(code).parse();
   * parser = new Parser(tokenSet, testLog);
   * parser.parse();
   * 
   * List<Parser.Function> functions = parser.getFunctions();
   * assertEquals(1, functions.size());
   * assertEquals("main", functions.get(0).name);
   * }
   * 
   * @Test
   * public void testParseComplexCode() {
   * String code =
   * "#include <stdio.h>\n" +
   * "int globalVar = 10;\n" +
   * "void helper(int x);\n" +
   * "int main() {\n" +
   * "    int localVar = 5;\n" +
   * "    helper(localVar);\n" +
   * "    return 0;\n" +
   * "}\n" +
   * "void helper(int x) {\n" +
   * "    printf(\"%d\", x);\n" +
   * "}";
   * 
   * tokenSet = new Tokenizer(code).parse();
   * parser = new Parser(tokenSet, testLog);
   * parser.parse();
   * 
   * List<Parser.Variable> variables = parser.getVariables();
   * List<Parser.Function> functions = parser.getFunctions();
   * List<Parser.FunctionCall> functionCalls = parser.getFunctionCalls();
   * 
   * assertEquals(2, variables.size());
   * assertEquals(2, functions.size());
   * assertEquals(2, functionCalls.size());
   * 
   * assertTrue(variables.stream().anyMatch(v -> v.name.equals("globalVar")));
   * assertTrue(variables.stream().anyMatch(v -> v.name.equals("localVar")));
   * assertTrue(functions.stream().anyMatch(f -> f.name.equals("main")));
   * assertTrue(functions.stream().anyMatch(f -> f.name.equals("helper")));
   * assertTrue(functionCalls.stream().anyMatch(fc -> fc.name.equals("helper")));
   * assertTrue(functionCalls.stream().anyMatch(fc -> fc.name.equals("printf")));
   * }
   */
}
