import { createWorkflowContext, createNodeContext } from '../../src/core/context';
import { NodeStatus } from '../../src/types';
import { describe, it, expect, jest } from '@jest/globals';

// Mocking uuid to have predictable IDs
jest.mock('uuid', () => ({
  v4: jest.fn().mockReturnValue('test-uuid-12345')
}));

describe('Context Module', () => {
  describe('createWorkflowContext', () => {
    it('should create a workflow context with minimal parameters', () => {
      const definitionId = 'test-workflow-definition';
      const input = { key: 'value' };
      
      const context = createWorkflowContext(definitionId, input);
      
      expect(context).toMatchObject({
        workflowId: 'test-uuid-12345',
        workflowDefinitionId: definitionId,
        input: { key: 'value' },
        status: NodeStatus.PENDING,
        variables: {},
        history: []
      });
      
      // Verify input was copied rather than referenced
      expect(context.input).not.toBe(input);
      expect(context.input).toEqual(input);
      
      // Verify startTime is set
      expect(context.startTime).toBeInstanceOf(Date);
    });
    
    it('should include optional parameters when provided', () => {
      const definitionId = 'test-workflow-definition';
      const input = { key: 'value' };
      const tenantId = 'tenant-123';
      const userId = 'user-456';
      const userRole = 'admin';
      
      const context = createWorkflowContext(definitionId, input, tenantId, userId, userRole);
      
      expect(context).toMatchObject({
        workflowId: 'test-uuid-12345',
        workflowDefinitionId: definitionId,
        input: { key: 'value' },
        status: NodeStatus.PENDING,
        variables: {},
        history: [],
        tenantId,
        userId,
        userRole
      });
    });
  });
  
  describe('createNodeContext', () => {
    it('should create a node context with required parameters', () => {
      const workflowContext = createWorkflowContext('test-def', {});
      const stepId = 'step-1';
      const nodeId = 'node-1';
      const input = { param: 'test' };
      
      const nodeContext = createNodeContext(workflowContext, stepId, nodeId, input);
      
      expect(nodeContext).toMatchObject({
        nodeId,
        stepId,
        input: { param: 'test' },
        status: NodeStatus.PENDING,
        retries: 0,
        logs: [],
        workflowContext
      });
      
      // Verify input was copied
      expect(nodeContext.input).not.toBe(input);
      expect(nodeContext.input).toEqual(input);
      
      // Verify workflowContext is referenced, not copied
      expect(nodeContext.workflowContext).toBe(workflowContext);
    });
    
    it('should use stepId as nodeId when nodeId is undefined', () => {
      const workflowContext = createWorkflowContext('test-def', {});
      const stepId = 'step-1';
      const input = { param: 'test' };
      
      const nodeContext = createNodeContext(workflowContext, stepId, undefined, input);
      
      expect(nodeContext.nodeId).toBe(stepId);
    });
  });
}); 