/**
 * @fileoverview Tests for example tool plugin
 */

import { describe, it, expect } from 'vitest';
import { toolSchema, handler, toolDefinition } from '../example.tool.js';

describe('Example Tool', () => {
  describe('toolSchema', () => {
    it('should have correct basic properties', () => {
      expect(toolSchema.name).toBe('example_tool');
      expect(toolSchema.description).toBe(
        'An example tool demonstrating the enhanced plugin format'
      );
      expect(toolSchema.inputSchema).toBeDefined();
      expect(toolSchema.outputSchema).toBeDefined();
    });

    it('should validate valid input', () => {
      const validInput = { message: 'Hello', count: 3 };
      const result = toolSchema.inputSchema.safeParse(validInput);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data).toEqual(validInput);
      }
    });

    it('should validate input with default count', () => {
      const inputWithoutCount = { message: 'Hello' };
      const result = toolSchema.inputSchema.safeParse(inputWithoutCount);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.count).toBe(1);
      }
    });

    it('should reject invalid input', () => {
      const invalidInput = { count: 3 }; // missing required message
      const result = toolSchema.inputSchema.safeParse(invalidInput);
      expect(result.success).toBe(false);
    });

    it('should validate expected output format', () => {
      const validOutput = {
        result: 'Hello Hello',
        processedAt: '2023-01-01T00:00:00.000Z',
        metadata: {
          messageLength: 5,
          repeatCount: 2,
        },
      };
      const result = toolSchema.outputSchema.safeParse(validOutput);
      expect(result.success).toBe(true);
    });
  });

  describe('handler', () => {
    it('should process single message', async () => {
      const params = { message: 'Hello', count: 1 };
      const result = await handler(params);

      expect(result.content).toHaveLength(1);
      expect(result.content[0]?.type).toBe('text');

      const textContent = result.content[0]?.text;
      expect(textContent).toBeDefined();
      if (!textContent) throw new Error('textContent is undefined');
      const responseData = JSON.parse(textContent);
      expect(responseData.result).toBe('Hello');
      expect(responseData.metadata.messageLength).toBe(5);
      expect(responseData.metadata.repeatCount).toBe(1);
      expect(responseData.processedAt).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
    });

    it('should repeat message multiple times', async () => {
      const params = { message: 'Test', count: 3 };
      const result = await handler(params);

      expect(result.content).toHaveLength(1);
      const textContent = result.content[0]?.text;
      expect(textContent).toBeDefined();
      if (!textContent) throw new Error('textContent is undefined');
      const responseData = JSON.parse(textContent);
      expect(responseData.result).toBe('Test Test Test');
      expect(responseData.metadata.messageLength).toBe(4);
      expect(responseData.metadata.repeatCount).toBe(3);
    });

    it('should handle default count when not provided', async () => {
      const params = { message: 'Default' };
      const result = await handler(params);

      expect(result.content).toHaveLength(1);
      const textContent = result.content[0]?.text;
      expect(textContent).toBeDefined();
      if (!textContent) throw new Error('textContent is undefined');
      const responseData = JSON.parse(textContent);
      expect(responseData.result).toBe('Default');
      expect(responseData.metadata.repeatCount).toBe(1);
    });

    it('should handle zero count', async () => {
      const params = { message: 'Zero', count: 0 };
      const result = await handler(params);

      expect(result.content).toHaveLength(1);
      const textContent = result.content[0]?.text;
      expect(textContent).toBeDefined();
      if (!textContent) throw new Error('textContent is undefined');
      const responseData = JSON.parse(textContent);
      expect(responseData.result).toBe('');
      expect(responseData.metadata.repeatCount).toBe(0);
    });

    it('should handle empty message', async () => {
      const params = { message: '', count: 2 };
      const result = await handler(params);

      expect(result.content).toHaveLength(1);
      const textContent = result.content[0]?.text;
      expect(textContent).toBeDefined();
      if (!textContent) throw new Error('textContent is undefined');
      const responseData = JSON.parse(textContent);
      expect(responseData.result).toBe(' ');
      expect(responseData.metadata.messageLength).toBe(0);
      expect(responseData.metadata.repeatCount).toBe(2);
    });

    it('should process with large count', async () => {
      const params = { message: 'Big', count: 10 };
      const result = await handler(params);

      expect(result.content).toHaveLength(1);
      const textContent = result.content[0]?.text;
      expect(textContent).toBeDefined();
      if (!textContent) throw new Error('textContent is undefined');
      const responseData = JSON.parse(textContent);
      const expectedResult = Array(10).fill('Big').join(' ');
      expect(responseData.result).toBe(expectedResult);
      expect(responseData.metadata.repeatCount).toBe(10);
    });
  });

  describe('toolDefinition', () => {
    it('should have correct structure', () => {
      expect(toolDefinition.name).toBe('example_tool');
      expect(toolDefinition.description).toBe(
        'An example tool demonstrating the enhanced plugin format'
      );
      expect(toolDefinition.handler).toBe(handler);
      expect(toolDefinition.inputSchema).toBe(toolSchema.inputSchema);
      expect(toolDefinition.outputSchema).toBe(toolSchema.outputSchema);
    });

    it('should have correct metadata', () => {
      expect(toolDefinition.metadata).toBeDefined();
      expect(toolDefinition.metadata?.category).toBe('utilities');
      expect(toolDefinition.metadata?.version).toBe('1.0.0');
      expect(toolDefinition.metadata?.tags).toEqual(['example', 'demo', 'text-processing']);
      expect(toolDefinition.metadata?.enabled).toBe(true);
    });

    it('should be callable through toolDefinition handler', async () => {
      const params = { message: 'Definition', count: 2 };
      const result = await toolDefinition.handler(params);

      expect(result.content).toHaveLength(1);
      const textContent = result.content[0]?.text;
      expect(textContent).toBeDefined();
      if (!textContent) throw new Error('textContent is undefined');
      const responseData = JSON.parse(textContent);
      expect(responseData.result).toBe('Definition Definition');
    });
  });
});
