import { describe, it, expect } from 'vitest';
import {
  normalizeJobRole,
  parseUiRole,
  resolveJobScheduling,
  buildSchedulingMetadataBlock,
} from './scheduling.js';

describe('normalizeJobRole', () => {
  it('passes through fast and quality', () => {
    expect(normalizeJobRole('fast')).toBe('fast');
    expect(normalizeJobRole('quality')).toBe('quality');
  });

  it('normalizes case and whitespace', () => {
    expect(normalizeJobRole('  FAST ')).toBe('fast');
    expect(normalizeJobRole('Quality')).toBe('quality');
  });

  it('falls back to auto for unknown, null, undefined and empty values', () => {
    expect(normalizeJobRole('turbo')).toBe('auto');
    expect(normalizeJobRole('')).toBe('auto');
    expect(normalizeJobRole(null)).toBe('auto');
    expect(normalizeJobRole(undefined)).toBe('auto');
    expect(normalizeJobRole('auto')).toBe('auto');
  });
});

describe('parseUiRole', () => {
  it('extracts the role from a ui_profile marker', () => {
    expect(parseUiRole('do stuff\n---\nui_profile: fast')).toBe('fast');
    expect(parseUiRole('ui_profile: quality')).toBe('quality');
  });

  it('is case-insensitive and tolerates spacing', () => {
    expect(parseUiRole('UI_PROFILE:   FAST')).toBe('fast');
    expect(parseUiRole('ui_profile:quality')).toBe('quality');
  });

  it('returns auto when no marker is present', () => {
    expect(parseUiRole('just an instruction')).toBe('auto');
    expect(parseUiRole('')).toBe('auto');
  });

  it('returns auto for a marker with an unknown value', () => {
    expect(parseUiRole('ui_profile: turbo')).toBe('auto');
  });
});

describe('resolveJobScheduling', () => {
  it('prefers an explicit role over the instruction marker', () => {
    const out = resolveJobScheduling({
      role: 'quality',
      pieceName: 'chat',
      instruction: 'ui_profile: fast',
    });
    expect(out).toEqual({ role: 'quality' });
  });

  it('falls back to the deprecated profile param', () => {
    const out = resolveJobScheduling({
      profile: 'fast',
      pieceName: 'chat',
      instruction: 'no marker',
    });
    expect(out).toEqual({ role: 'fast' });
  });

  it('role wins over deprecated profile when both are set', () => {
    const out = resolveJobScheduling({
      role: 'fast',
      profile: 'quality',
      pieceName: 'chat',
      instruction: '',
    });
    expect(out).toEqual({ role: 'fast' });
  });

  it('parses the instruction marker when no explicit role is given', () => {
    const out = resolveJobScheduling({
      pieceName: 'chat',
      instruction: 'task body\nui_profile: quality',
    });
    expect(out).toEqual({ role: 'quality' });
  });

  it('returns auto when nothing specifies a role', () => {
    const out = resolveJobScheduling({ pieceName: 'chat', instruction: 'plain' });
    expect(out).toEqual({ role: 'auto' });
  });

  it('treats role auto as "not explicit" and still reads the marker', () => {
    const out = resolveJobScheduling({
      role: 'auto',
      pieceName: 'chat',
      instruction: 'ui_profile: fast',
    });
    expect(out).toEqual({ role: 'fast' });
  });
});

describe('buildSchedulingMetadataBlock', () => {
  it('renders a parseable marker block', () => {
    const block = buildSchedulingMetadataBlock('fast');
    expect(block).toBe('---\nui_profile: fast');
    expect(parseUiRole(block)).toBe('fast');
  });

  it('round-trips every role', () => {
    for (const role of ['auto', 'fast', 'quality'] as const) {
      expect(parseUiRole(buildSchedulingMetadataBlock(role))).toBe(role);
    }
  });
});
