import { test } from 'node:test';
import assert from 'node:assert/strict';
import { MsgType } from 'matrix-js-sdk';
import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
import { getAudioMsgContent, getFileMsgContent } from './msgContent';
import { TUploadItem } from '../../state/room/roomInputDrafts';

// Pure builders getAudioMsgContent / getFileMsgContent: msgtype/body/filename/info
// shape plus the encInfo branch (content.file w/ url vs plain content.url). The
// image/video builders need a DOM + MatrixClient and are not covered here.

const MXC = 'mxc://example.org/abc';

const makeItem = (encInfo?: EncryptedAttachmentInfo): TUploadItem => {
  const file = { name: 'sound.ogg', type: 'audio/ogg', size: 4096 };
  return {
    file,
    originalFile: file,
    metadata: { markedAsSpoiler: false },
    encInfo,
  } as unknown as TUploadItem;
};

const fakeEncInfo = (): EncryptedAttachmentInfo =>
  ({
    v: 'v2',
    key: { alg: 'A256CTR' },
    iv: 'iv',
    hashes: { sha256: 'h' },
  }) as unknown as EncryptedAttachmentInfo;

test('getAudioMsgContent builds an unencrypted audio message', () => {
  const content = getAudioMsgContent(makeItem(), MXC);
  assert.equal(content.msgtype, MsgType.Audio);
  assert.equal(content.body, 'sound.ogg');
  assert.equal(content.filename, 'sound.ogg');
  assert.deepEqual(content.info, { mimetype: 'audio/ogg', size: 4096 });
  assert.equal(content.url, MXC);
  assert.equal(content.file, undefined);
});

test('getAudioMsgContent uses content.file with url when encInfo is present', () => {
  const enc = fakeEncInfo();
  const content = getAudioMsgContent(makeItem(enc), MXC);
  assert.equal(content.url, undefined);
  assert.deepEqual(content.file, { ...enc, url: MXC });
});

test('getFileMsgContent builds an unencrypted file message', () => {
  const content = getFileMsgContent(makeItem(), MXC);
  assert.equal(content.msgtype, MsgType.File);
  assert.equal(content.body, 'sound.ogg');
  assert.equal(content.filename, 'sound.ogg');
  assert.deepEqual(content.info, { mimetype: 'audio/ogg', size: 4096 });
  assert.equal(content.url, MXC);
  assert.equal(content.file, undefined);
});

test('getFileMsgContent uses content.file with url when encInfo is present', () => {
  const enc = fakeEncInfo();
  const content = getFileMsgContent(makeItem(enc), MXC);
  assert.equal(content.url, undefined);
  assert.deepEqual(content.file, { ...enc, url: MXC });
});

test('info mirrors the file mimetype and size', () => {
  const item = {
    file: { name: 'doc.pdf', type: 'application/pdf', size: 12 },
    originalFile: { name: 'doc.pdf', type: 'application/pdf', size: 12 },
    metadata: { markedAsSpoiler: false },
    encInfo: undefined,
  } as unknown as TUploadItem;
  const content = getFileMsgContent(item, MXC);
  assert.deepEqual(content.info, { mimetype: 'application/pdf', size: 12 });
  assert.equal(content.body, 'doc.pdf');
});
