/**
 * @fileoverview Dead Code Eliminator Tests
 */

import { beforeEach, describe, expect, it } from 'vitest';
import {
    ExpressionType,
    StatementType,
    type ClientBlockNode,
    type ComponentAST,
    type FunctionNode,
    type MarkupBlockNode,
    type ReactiveVariableNode,
    type ServerBlockNode
} from '../types/index.js';
import { DeadCodeEliminator } from './dead-code-eliminator.js';

describe('DeadCodeEliminator', () => {
  let eliminator: DeadCodeEliminator;

  beforeEach(() => {
    eliminator = new DeadCodeEliminator();
  });

  describe('constructor', () => {
    it('should initialize with default options', () => {
      expect(eliminator).toBeInstanceOf(DeadCodeEliminator);
    });

    it('should accept custom options', () => {
      const customEliminator = new DeadCodeEliminator({
        aggressiveTreeShaking: false,
        inlineSmallFunctions: false,
        maxInlineSize: 5
      });
      expect(customEliminator).toBeInstanceOf(DeadCodeEliminator);
    });
  });

  describe('optimize', () => {
    it('should return the same AST when no optimizations are possible', () => {
      const ast = createSimpleAST();
      const result = eliminator.optimize(ast);
      expect(result).toBe(ast);
    });

    it('should remove unused reactive variables', () => {
      const ast = createASTWithUnusedVariables();
      const originalVariableCount = ast.component.clientBlock!.reactiveVariables.length;

      const result = eliminator.optimize(ast);

      expect(result.component.clientBlock!.reactiveVariables.length).toBeLessThan(originalVariableCount);
      expect(result.component.clientBlock!.reactiveVariables.every(v => v.name === 'usedVariable')).toBe(true);
    });

    it('should remove unused functions', () => {
      const ast = createASTWithUnusedFunctions();
      const originalFunctionCount = ast.component.clientBlock!.functions.length;

      const result = eliminator.optimize(ast);

      expect(result.component.clientBlock!.functions.length).toBeLessThan(originalFunctionCount);
      expect(result.component.clientBlock!.functions.every(f => f.name === 'usedFunction')).toBe(true);
    });

    it('should remove unused event handlers', () => {
      const ast = createASTWithUnusedEventHandlers();
      const originalHandlerCount = ast.component.clientBlock!.eventHandlers.length;

      const result = eliminator.optimize(ast);

      expect(result.component.clientBlock!.eventHandlers.length).toBeLessThan(originalHandlerCount);
      expect(result.component.clientBlock!.eventHandlers.every(h => h.eventName === 'click')).toBe(true);
    });

    it('should remove unused server functions', () => {
      const ast = createASTWithUnusedServerFunctions();
      const originalFunctionCount = ast.component.serverBlock!.functions.length;

      const result = eliminator.optimize(ast);

      expect(result.component.serverBlock!.functions.length).toBeLessThan(originalFunctionCount);
      expect(result.component.serverBlock!.functions.every(f => f.isPublic || f.name === 'usedFunction')).toBe(true);
    });

    it('should perform constant folding', () => {
      const ast = createASTWithConstantExpressions();
      const result = eliminator.optimize(ast);

      // Check that constant expressions were folded
      const warnings = eliminator.getWarnings();
      expect(warnings.some(w => w.message.includes('constant folding'))).toBe(true);
    });

    it('should remove empty blocks', () => {
      const ast = createASTWithEmptyBlocks();
      const result = eliminator.optimize(ast);

      const warnings = eliminator.getWarnings();
      expect(warnings.some(w => w.message.includes('empty blocks'))).toBe(true);
    });

    it('should handle errors gracefully', () => {
      const invalidAST = createInvalidAST();

      expect(() => eliminator.optimize(invalidAST)).toThrow();

      const errors = eliminator.getErrors();
      expect(errors.length).toBeGreaterThan(0);
      expect(errors[0]).toBeInstanceOf(Error);
    });

    it('should generate warnings for optimizations', () => {
      const ast = createASTWithUnusedVariables();
      eliminator.optimize(ast);

      const warnings = eliminator.getWarnings();
      expect(warnings.length).toBeGreaterThan(0);
      expect(warnings.every(w => w instanceof Error)).toBe(true);
    });

    it('should preserve used variables and functions', () => {
      const ast = createASTWithUsedAndUnused();
      const result = eliminator.optimize(ast);

      // Check that used variables are preserved
      const usedVariables = result.component.clientBlock!.reactiveVariables.map(v => v.name);
      expect(usedVariables).toContain('usedVariable');
      expect(usedVariables).not.toContain('unusedVariable');

      // Check that used functions are preserved
      const usedFunctions = result.component.clientBlock!.functions.map(f => f.name);
      expect(usedFunctions).toContain('usedFunction');
      expect(usedFunctions).not.toContain('unusedFunction');
    });

    it('should handle complex nested expressions', () => {
      const ast = createASTWithComplexExpressions();
      const result = eliminator.optimize(ast);

      expect(result).toBeDefined();
      expect(result.component).toBeDefined();
    });

    it('should handle components without client or server blocks', () => {
      const ast = createASTWithoutBlocks();
      const result = eliminator.optimize(ast);

      expect(result).toBe(ast);
    });
  });

  describe('error handling', () => {
    it('should handle null AST gracefully', () => {
      expect(() => eliminator.optimize(null as any)).toThrow();
    });

    it('should handle undefined AST gracefully', () => {
      expect(() => eliminator.optimize(undefined as any)).toThrow();
    });

    it('should handle malformed AST gracefully', () => {
      const malformedAST = createMalformedAST();
      expect(() => eliminator.optimize(malformedAST)).toThrow();
    });
  });

  describe('options', () => {
    it('should respect aggressiveTreeShaking option', () => {
      const conservativeEliminator = new DeadCodeEliminator({
        aggressiveTreeShaking: false
      });

      const ast = createASTWithUnusedVariables();
      const result = conservativeEliminator.optimize(ast);

      // Should be less aggressive in removal
      expect(result.component.clientBlock!.reactiveVariables.length).toBeGreaterThanOrEqual(
        ast.component.clientBlock!.reactiveVariables.length
      );
    });

    it('should respect inlineSmallFunctions option', () => {
      const noInlineEliminator = new DeadCodeEliminator({
        inlineSmallFunctions: false
      });

      const ast = createASTWithSmallFunctions();
      const result = noInlineEliminator.optimize(ast);

      const warnings = noInlineEliminator.getWarnings();
      expect(warnings.some(w => w.message.includes('inlining'))).toBe(false);
    });

    it('should respect maxInlineSize option', () => {
      const smallInlineEliminator = new DeadCodeEliminator({
        maxInlineSize: 2
      });

      const ast = createASTWithSmallFunctions();
      const result = smallInlineEliminator.optimize(ast);

      // Should inline fewer functions with smaller maxInlineSize
      const warnings = smallInlineEliminator.getWarnings();
      const inliningWarnings = warnings.filter(w => w.message.includes('inlining'));
      expect(inliningWarnings.length).toBeLessThanOrEqual(2);
    });
  });
});

// Helper functions to create test ASTs

function createSimpleAST(): ComponentAST {
  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      markupBlock: {
        type: 'MarkupBlock',
        elements: [],
        textNodes: [],
        interpolations: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithUnusedVariables(): ComponentAST {
  const usedVariable: ReactiveVariableNode = {
    type: 'ReactiveVariable',
    name: 'usedVariable',
    initialValue: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 42, range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
    dataType: { name: 'number', isArray: false, isOptional: false, genericTypes: [] },
    isConst: false,
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const unusedVariable: ReactiveVariableNode = {
    type: 'ReactiveVariable',
    name: 'unusedVariable',
    initialValue: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 100, range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
    dataType: { name: 'number', isArray: false, isOptional: false, genericTypes: [] },
    isConst: false,
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const clientBlock: ClientBlockNode = {
    type: 'ClientBlock',
    reactiveVariables: [usedVariable, unusedVariable],
    eventHandlers: [],
    functions: [],
    lifecycle: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const markupBlock: MarkupBlockNode = {
    type: 'MarkupBlock',
    elements: [],
    textNodes: [],
    interpolations: [{
      type: 'Interpolation',
      expression: { type: 'Expression', expressionType: ExpressionType.IDENTIFIER, identifier: 'usedVariable', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    }],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      clientBlock,
      markupBlock,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithUnusedFunctions(): ComponentAST {
  const usedFunction: FunctionNode = {
    type: 'Function',
    name: 'usedFunction',
    parameters: [],
    body: [],
    returnType: { name: 'void', isArray: false, isOptional: false, genericTypes: [] },
    isAsync: false,
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const unusedFunction: FunctionNode = {
    type: 'Function',
    name: 'unusedFunction',
    parameters: [],
    body: [],
    returnType: { name: 'void', isArray: false, isOptional: false, genericTypes: [] },
    isAsync: false,
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const clientBlock: ClientBlockNode = {
    type: 'ClientBlock',
    reactiveVariables: [],
    eventHandlers: [],
    functions: [usedFunction, unusedFunction],
    lifecycle: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const markupBlock: MarkupBlockNode = {
    type: 'MarkupBlock',
    elements: [],
    textNodes: [],
    interpolations: [{
      type: 'Interpolation',
      expression: { type: 'Expression', expressionType: ExpressionType.CALL, callee: { type: 'Expression', expressionType: ExpressionType.IDENTIFIER, identifier: 'usedFunction', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } }, arguments: [], range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    }],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      clientBlock,
      markupBlock,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithUnusedEventHandlers(): ComponentAST {
  const clientBlock: ClientBlockNode = {
    type: 'ClientBlock',
    reactiveVariables: [],
    eventHandlers: [
      {
        type: 'EventHandler',
        eventName: 'click',
        handler: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 'handleClick', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
        modifiers: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      {
        type: 'EventHandler',
        eventName: 'unused',
        handler: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 'handleUnused', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
        modifiers: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      }
    ],
    functions: [],
    lifecycle: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const markupBlock: MarkupBlockNode = {
    type: 'MarkupBlock',
    elements: [{
      type: 'HTMLElement',
      tagName: 'button',
      attributes: [{ type: 'Attribute', name: 'onclick', value: 'click', isDirective: false, range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } }],
      children: [],
      isSelfClosing: false,
      isVoidElement: false,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    }],
    textNodes: [],
    interpolations: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      clientBlock,
      markupBlock,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithUnusedServerFunctions(): ComponentAST {
  const serverBlock: ServerBlockNode = {
    type: 'ServerBlock',
    functions: [
      {
        type: 'ServerFunction',
        name: 'usedFunction',
        parameters: [],
        body: [],
        returnType: { name: 'void', isArray: false, isOptional: false, genericTypes: [] },
        isAsync: false,
        isPublic: false,
        middleware: [],
        permissions: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      {
        type: 'ServerFunction',
        name: 'unusedFunction',
        parameters: [],
        body: [],
        returnType: { name: 'void', isArray: false, isOptional: false, genericTypes: [] },
        isAsync: false,
        isPublic: false,
        middleware: [],
        permissions: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      }
    ],
    middleware: [],
    dataFetchers: [],
    imports: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      serverBlock,
      markupBlock: {
        type: 'MarkupBlock',
        elements: [],
        textNodes: [],
        interpolations: [{
          type: 'Interpolation',
          expression: { type: 'Expression', expressionType: ExpressionType.CALL, callee: { type: 'Expression', expressionType: ExpressionType.IDENTIFIER, identifier: 'usedFunction', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } }, arguments: [], range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
          range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
        }],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithConstantExpressions(): ComponentAST {
  const clientBlock: ClientBlockNode = {
    type: 'ClientBlock',
    reactiveVariables: [],
    eventHandlers: [],
    functions: [{
      type: 'Function',
      name: 'testFunction',
      parameters: [],
      body: [{
        type: 'Statement',
        statementType: StatementType.EXPRESSION,
        expression: {
          type: 'Expression',
          expressionType: ExpressionType.BINARY,
          operator: '+',
          left: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 2, range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
          right: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 3, range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
          range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
        },
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      }],
      returnType: { name: 'number', isArray: false, isOptional: false, genericTypes: [] },
      isAsync: false,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    }],
    lifecycle: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      clientBlock,
      markupBlock: {
        type: 'MarkupBlock',
        elements: [],
        textNodes: [],
        interpolations: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithEmptyBlocks(): ComponentAST {
  const clientBlock: ClientBlockNode = {
    type: 'ClientBlock',
    reactiveVariables: [],
    eventHandlers: [],
    functions: [{
      type: 'Function',
      name: 'testFunction',
      parameters: [],
      body: [{
        type: 'Statement',
        statementType: StatementType.BLOCK,
        body: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      }],
      returnType: { name: 'void', isArray: false, isOptional: false, genericTypes: [] },
      isAsync: false,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    }],
    lifecycle: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      clientBlock,
      markupBlock: {
        type: 'MarkupBlock',
        elements: [],
        textNodes: [],
        interpolations: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithUsedAndUnused(): ComponentAST {
  const usedVariable: ReactiveVariableNode = {
    type: 'ReactiveVariable',
    name: 'usedVariable',
    initialValue: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 42, range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
    dataType: { name: 'number', isArray: false, isOptional: false, genericTypes: [] },
    isConst: false,
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const unusedVariable: ReactiveVariableNode = {
    type: 'ReactiveVariable',
    name: 'unusedVariable',
    initialValue: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 100, range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
    dataType: { name: 'number', isArray: false, isOptional: false, genericTypes: [] },
    isConst: false,
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const usedFunction: FunctionNode = {
    type: 'Function',
    name: 'usedFunction',
    parameters: [],
    body: [],
    returnType: { name: 'void', isArray: false, isOptional: false, genericTypes: [] },
    isAsync: false,
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const unusedFunction: FunctionNode = {
    type: 'Function',
    name: 'unusedFunction',
    parameters: [],
    body: [],
    returnType: { name: 'void', isArray: false, isOptional: false, genericTypes: [] },
    isAsync: false,
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const clientBlock: ClientBlockNode = {
    type: 'ClientBlock',
    reactiveVariables: [usedVariable, unusedVariable],
    eventHandlers: [],
    functions: [usedFunction, unusedFunction],
    lifecycle: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  const markupBlock: MarkupBlockNode = {
    type: 'MarkupBlock',
    elements: [],
    textNodes: [],
    interpolations: [
      {
        type: 'Interpolation',
        expression: { type: 'Expression', expressionType: ExpressionType.IDENTIFIER, identifier: 'usedVariable', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      {
        type: 'Interpolation',
        expression: { type: 'Expression', expressionType: ExpressionType.CALL, callee: { type: 'Expression', expressionType: ExpressionType.IDENTIFIER, identifier: 'usedFunction', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } }, arguments: [], range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      }
    ],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      clientBlock,
      markupBlock,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithComplexExpressions(): ComponentAST {
  const clientBlock: ClientBlockNode = {
    type: 'ClientBlock',
    reactiveVariables: [],
    eventHandlers: [],
    functions: [{
      type: 'Function',
      name: 'complexFunction',
      parameters: [],
      body: [{
        type: 'Statement',
        statementType: StatementType.EXPRESSION,
        expression: {
          type: 'Expression',
          expressionType: ExpressionType.CALL,
          callee: {
            type: 'Expression',
            expressionType: ExpressionType.MEMBER,
            object: { type: 'Expression', expressionType: ExpressionType.IDENTIFIER, identifier: 'console', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
            property: { type: 'Expression', expressionType: ExpressionType.IDENTIFIER, identifier: 'log', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
            range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
          },
          arguments: [
            {
              type: 'Expression',
              expressionType: ExpressionType.BINARY,
              operator: '+',
              left: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 'Hello', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
              right: { type: 'Expression', expressionType: ExpressionType.IDENTIFIER, identifier: 'name', range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
              range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
            }
          ],
          range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
        },
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      }],
      returnType: { name: 'void', isArray: false, isOptional: false, genericTypes: [] },
      isAsync: false,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    }],
    lifecycle: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      clientBlock,
      markupBlock: {
        type: 'MarkupBlock',
        elements: [],
        textNodes: [],
        interpolations: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithoutBlocks(): ComponentAST {
  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      markupBlock: {
        type: 'MarkupBlock',
        elements: [],
        textNodes: [],
        interpolations: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createASTWithSmallFunctions(): ComponentAST {
  const clientBlock: ClientBlockNode = {
    type: 'ClientBlock',
    reactiveVariables: [],
    eventHandlers: [],
    functions: [{
      type: 'Function',
      name: 'smallFunction',
      parameters: [],
      body: [{
        type: 'Statement',
        statementType: StatementType.EXPRESSION,
        expression: { type: 'Expression', expressionType: ExpressionType.LITERAL, value: 42, range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } } },
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      }],
      returnType: { name: 'number', isArray: false, isOptional: false, genericTypes: [] },
      isAsync: false,
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    }],
    lifecycle: [],
    range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
  };

  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      clientBlock,
      markupBlock: {
        type: 'MarkupBlock',
        elements: [],
        textNodes: [],
        interpolations: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    },
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createInvalidAST(): ComponentAST {
  return {
    component: {
      type: 'Component',
      name: 'TestComponent',
      props: [],
      markupBlock: {
        type: 'MarkupBlock',
        elements: [],
        textNodes: [],
        interpolations: [],
        range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
      },
      range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 } }
    } as any, // Force invalid AST
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}

function createMalformedAST(): ComponentAST {
  return {
    component: null as any,
    dependencies: [],
    exports: [],
    sourceMap: {
      version: 3,
      sources: [],
      names: [],
      mappings: '',
      sourcesContent: []
    }
  };
}
