import { describe, expect, test } from 'bun:test';
import { validatePublicKey } from './os-user-ssh';

// `authorized_keys` is a file where every LINE is a credential, so the validation that matters is not
// "does this look like a key" — it is "is this exactly one".

describe('validatePublicKey', () => {
  const ed25519 = 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHhTb2Rhb25lc3RyaW5nb2ZiYXNlNjRoZXJlMTIz ana@laptop';

  test('accepts an ed25519 key with a comment', () => {
    expect(validatePublicKey(ed25519)).toEqual({ ok: true, key: ed25519 });
  });

  test('accepts one with no comment, and trims surrounding whitespace', () => {
    const bare = 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHhTb2Rhb25lc3RyaW5nb2ZiYXNlNjRoZXJlMTIz';
    expect(validatePublicKey(`  ${bare}\n`)).toEqual({ ok: true, key: bare });
  });

  test('accepts rsa and ecdsa', () => {
    expect(validatePublicKey('ssh-rsa AAAAB3NzaC1yc2EAAAAsomethinglongenough== a@b').ok).toBe(true);
    expect(validatePublicKey('ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY= a@b').ok).toBe(true);
  });

  // THE case this function exists for. A second line is a second authorized key, and it would be granted
  // silently — the caller only ever looks at whether the write succeeded.
  test('refuses a second line, which would inject a second credential', () => {
    const injected = `${ed25519}\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEludHJ1ZGVyc0tleUhlcmVQYWRkaW5nMTIz attacker@elsewhere`;
    const result = validatePublicKey(injected);
    expect(result.ok).toBe(false);
    expect(result).toMatchObject({ error: expect.stringContaining('single line') });
  });

  test('refuses a carriage return too', () => {
    expect(validatePublicKey(`${ed25519}\r\nssh-rsa AAAAB3Nz== x@y`).ok).toBe(false);
  });

  // Pasting the private half instead of the .pub is a genuine mistake, and it deserves a message that
  // says so rather than "not a public key".
  test('names the mistake when handed a private key', () => {
    const priv = '-----BEGIN OPENSSH PRIVATE KEY-----';
    expect(validatePublicKey(priv)).toMatchObject({ ok: false, error: expect.stringContaining('PRIVATE') });
  });

  test('refuses junk, an empty string and a bare algorithm name', () => {
    expect(validatePublicKey('hello').ok).toBe(false);
    expect(validatePublicKey('').ok).toBe(false);
    expect(validatePublicKey('ssh-ed25519').ok).toBe(false);
    expect(validatePublicKey('ssh-ed25519 not!valid!base64!').ok).toBe(false);
  });

  // An `authorized_keys` options prefix (`command="…" ssh-ed25519 …`) is a legitimate OpenSSH line but not
  // something this form should accept: it can force a command or disable a restriction, and it is not what
  // anyone pastes by accident.
  test('refuses an options prefix', () => {
    expect(validatePublicKey(`command="/bin/sh" ${ed25519}`).ok).toBe(false);
  });
});
