import { describe, it, expect } from 'vitest';
import {
  CreateMcpServerSchema,
  UpdateMcpServerSchema,
} from '../src/validation/index.js';

describe('CreateMcpServerSchema', () => {
  it('validates valid input', () => {
    const result = CreateMcpServerSchema.parse({
      name: 'my-server',
      description: 'A test server',
      transport: 'STDIO',
    });
    expect(result.name).toBe('my-server');
    expect(result.env).toEqual([]);
  });

  it('rejects empty name', () => {
    expect(() => CreateMcpServerSchema.parse({ name: '' })).toThrow();
  });

  it('rejects name with spaces', () => {
    expect(() => CreateMcpServerSchema.parse({ name: 'my server' })).toThrow();
  });

  it('rejects uppercase name', () => {
    expect(() => CreateMcpServerSchema.parse({ name: 'MyServer' })).toThrow();
  });

  it('allows hyphens in name', () => {
    const result = CreateMcpServerSchema.parse({ name: 'my-mcp-server' });
    expect(result.name).toBe('my-mcp-server');
  });

  it('defaults transport to STDIO', () => {
    const result = CreateMcpServerSchema.parse({ name: 'test' });
    expect(result.transport).toBe('STDIO');
  });

  it('validates env entries with inline value', () => {
    const result = CreateMcpServerSchema.parse({
      name: 'test',
      env: [
        { name: 'API_URL', value: 'https://example.com' },
      ],
    });
    expect(result.env).toHaveLength(1);
    expect(result.env[0]?.value).toBe('https://example.com');
  });

  it('validates env entries with secretRef', () => {
    const result = CreateMcpServerSchema.parse({
      name: 'test',
      env: [
        { name: 'API_KEY', valueFrom: { secretRef: { name: 'my-secret', key: 'api-key' } } },
      ],
    });
    expect(result.env).toHaveLength(1);
    expect(result.env[0]?.valueFrom?.secretRef.name).toBe('my-secret');
  });

  it('rejects env entry with neither value nor valueFrom', () => {
    expect(() => CreateMcpServerSchema.parse({
      name: 'test',
      env: [{ name: 'FOO' }],
    })).toThrow();
  });

  it('rejects env entry with both value and valueFrom', () => {
    expect(() => CreateMcpServerSchema.parse({
      name: 'test',
      env: [{ name: 'FOO', value: 'bar', valueFrom: { secretRef: { name: 'x', key: 'y' } } }],
    })).toThrow();
  });

  it('rejects invalid transport', () => {
    expect(() => CreateMcpServerSchema.parse({ name: 'test', transport: 'HTTP' })).toThrow();
  });

  it('rejects invalid repository URL', () => {
    expect(() => CreateMcpServerSchema.parse({ name: 'test', repositoryUrl: 'not-a-url' })).toThrow();
  });
});

describe('UpdateMcpServerSchema', () => {
  it('allows partial updates', () => {
    const result = UpdateMcpServerSchema.parse({ description: 'updated' });
    expect(result.description).toBe('updated');
    expect(result.transport).toBeUndefined();
  });

  it('allows empty object', () => {
    const result = UpdateMcpServerSchema.parse({});
    expect(Object.keys(result)).toHaveLength(0);
  });

  it('allows nullable fields', () => {
    const result = UpdateMcpServerSchema.parse({ packageName: null, dockerImage: null });
    expect(result.packageName).toBeNull();
    expect(result.dockerImage).toBeNull();
  });
});

