import { describe, it, expect } from 'vitest';
import {
  availableVariables,
  extractReferences,
  unknownReferences,
} from './alert-variables';

describe('availableVariables', () => {
  it('returns only always-available vars when kind is undefined', () => {
    const vars = availableVariables(undefined);
    expect(vars.find((v) => v.path === 'env.slug')).toBeTruthy();
    expect(vars.find((v) => v.path === 'exchange.id')).toBeUndefined();
    expect(vars.find((v) => v.path === 'log.pattern')).toBeUndefined();
    expect(vars.find((v) => v.path === 'app.slug')).toBeUndefined();
  });

  it('adds exchange.* + route.* + app.* for EXCHANGE_MATCH kind', () => {
    const vars = availableVariables('EXCHANGE_MATCH');
    expect(vars.find((v) => v.path === 'exchange.id')).toBeTruthy();
    expect(vars.find((v) => v.path === 'route.uri')).toBeTruthy();
    expect(vars.find((v) => v.path === 'app.slug')).toBeTruthy();
    expect(vars.find((v) => v.path === 'log.pattern')).toBeUndefined();
  });

  it('adds log.* + app.* for LOG_PATTERN kind', () => {
    const vars = availableVariables('LOG_PATTERN');
    expect(vars.find((v) => v.path === 'log.pattern')).toBeTruthy();
    expect(vars.find((v) => v.path === 'log.matchCount')).toBeTruthy();
    expect(vars.find((v) => v.path === 'app.slug')).toBeTruthy();
    expect(vars.find((v) => v.path === 'exchange.id')).toBeUndefined();
  });

  it('reduces to env-only when reducedContext=true (connection URL editor)', () => {
    const vars = availableVariables('ROUTE_METRIC', { reducedContext: true });
    expect(vars.every((v) => v.path.startsWith('env.'))).toBe(true);
  });
});

describe('extractReferences', () => {
  it('finds bare variable refs', () => {
    expect(extractReferences('Hello {{user.name}}, ack: {{alert.ackedBy}}')).toEqual([
      'user.name',
      'alert.ackedBy',
    ]);
  });
  it('ignores section/comment tags', () => {
    expect(
      extractReferences('{{#items}}{{name}}{{/items}} {{!comment}}'),
    ).toEqual(['name']);
  });
  it('tolerates whitespace', () => {
    expect(extractReferences('{{   alert.firedAt   }}')).toEqual(['alert.firedAt']);
  });
});

describe('unknownReferences', () => {
  it('flags references not in the allowed set', () => {
    const allowed = availableVariables('ROUTE_METRIC');
    expect(unknownReferences('{{alert.id}} {{exchange.id}}', allowed)).toEqual(['exchange.id']);
  });
});
