import { AssetFace, AssetFile, Exif } from 'src/database';
import { MapAsset } from 'src/dtos/asset-response.dto';
import { AssetEditAction, AssetEditActionItem } from 'src/dtos/editing.dto';
import { AssetFileType, AssetStatus, AssetType, AssetVisibility } from 'src/enum';
import { StorageAsset } from 'src/types';
import { authStub } from 'test/fixtures/auth.stub';
import { fileStub } from 'test/fixtures/file.stub';
import { userStub } from 'test/fixtures/user.stub';
import { factory } from 'test/small.factory';

export const previewFile = factory.assetFile({ type: AssetFileType.Preview });

const thumbnailFile = factory.assetFile({
  type: AssetFileType.Thumbnail,
  path: '/uploads/user-id/webp/path.ext',
});

const fullsizeFile = factory.assetFile({
  type: AssetFileType.FullSize,
  path: '/uploads/user-id/fullsize/path.webp',
});

const sidecarFileWithExt = factory.assetFile({
  type: AssetFileType.Sidecar,
  path: '/original/path.ext.xmp',
});

const sidecarFileWithoutExt = factory.assetFile({
  type: AssetFileType.Sidecar,
  path: '/original/path.xmp',
});

const editedPreviewFile = factory.assetFile({
  type: AssetFileType.PreviewEdited,
  path: '/uploads/user-id/preview/path_edited.jpg',
});

const editedThumbnailFile = factory.assetFile({
  type: AssetFileType.ThumbnailEdited,
  path: '/uploads/user-id/thumbnail/path_edited.jpg',
});

const editedFullsizeFile = factory.assetFile({
  type: AssetFileType.FullSizeEdited,
  path: '/uploads/user-id/fullsize/path_edited.jpg',
});

const files: AssetFile[] = [fullsizeFile, previewFile, thumbnailFile];

const editedFiles: AssetFile[] = [
  fullsizeFile,
  previewFile,
  thumbnailFile,
  editedFullsizeFile,
  editedPreviewFile,
  editedThumbnailFile,
];

export const stackStub = (stackId: string, assets: (MapAsset & { exifInfo: Exif })[]) => {
  return {
    id: stackId,
    assets,
    ownerId: assets[0].ownerId,
    primaryAsset: assets[0],
    primaryAssetId: assets[0].id,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    updateId: expect.any(String),
  };
};

export const assetStub = {
  storageAsset: (asset: Partial<StorageAsset> = {}) => ({
    id: 'asset-id',
    ownerId: 'user-id',
    livePhotoVideoId: null,
    type: AssetType.Image,
    isExternal: false,
    checksum: Buffer.from('file hash'),
    timeZone: null,
    fileCreatedAt: new Date('2022-06-19T23:41:36.910Z'),
    originalPath: '/original/path.jpg',
    originalFileName: 'IMG_123.jpg',
    fileSizeInByte: 12_345,
    files: [],
    make: 'FUJIFILM',
    model: 'X-T50',
    lensModel: 'XF27mm F2.8 R WR',
    ...asset,
  }),
  noResizePath: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    originalFileName: 'IMG_123.jpg',
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/data/library/IMG_123.jpg',
    files: [thumbnailFile],
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    faces: [],
    exifInfo: {} as Exif,
    deletedAt: null,
    isExternal: false,
    duplicateId: null,
    isOffline: false,
    libraryId: null,
    stackId: null,
    updateId: '42',
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  noWebpPath: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/data/library/IMG_456.jpg',
    files: [previewFile],
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'IMG_456.jpg',
    faces: [],
    isExternal: false,
    exifInfo: {
      fileSizeInByte: 123_000,
    } as Exif,
    deletedAt: null,
    duplicateId: null,
    isOffline: false,
    libraryId: null,
    stackId: null,
    updateId: '42',
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  noThumbhash: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.ext',
    files,
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    thumbhash: null,
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.ext',
    faces: [],
    deletedAt: null,
    duplicateId: null,
    isOffline: false,
    libraryId: null,
    stackId: null,
    updateId: '42',
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  primaryImage: Object.freeze({
    id: 'primary-asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.admin,
    ownerId: 'admin-id',
    deviceId: 'device-id',
    originalPath: '/original/path.jpg',
    checksum: Buffer.from('file hash', 'utf8'),
    files,
    type: AssetType.Image,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.jpg',
    faces: [],
    deletedAt: null,
    exifInfo: {
      fileSizeInByte: 5000,
      exifImageHeight: 1000,
      exifImageWidth: 1000,
    } as Exif,
    stackId: 'stack-1',
    stack: stackStub('stack-1', [
      { id: 'primary-asset-id' } as MapAsset & { exifInfo: Exif },
      { id: 'stack-child-asset-1' } as MapAsset & { exifInfo: Exif },
      { id: 'stack-child-asset-2' } as MapAsset & { exifInfo: Exif },
    ]),
    duplicateId: null,
    isOffline: false,
    updateId: '42',
    libraryId: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  image: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.jpg',
    files,
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2025-01-01T01:02:03.456Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    updateId: 'foo',
    libraryId: null,
    stackId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.jpg',
    faces: [],
    deletedAt: null,
    exifInfo: {
      fileSizeInByte: 5000,
      exifImageHeight: 3840,
      exifImageWidth: 2160,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    stack: null,
    orientation: '',
    projectionType: null,
    height: null,
    width: null,
    visibility: AssetVisibility.Timeline,
    edits: [],
  }),

  trashed: Object.freeze({
    id: 'asset-id',
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.jpg',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    deletedAt: new Date('2023-02-24T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: false,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.jpg',
    faces: [],
    exifInfo: {
      fileSizeInByte: 5000,
      exifImageHeight: 3840,
      exifImageWidth: 2160,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    status: AssetStatus.Trashed,
    libraryId: null,
    stackId: null,
    updateId: '42',
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  trashedOffline: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.jpg',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    deletedAt: new Date('2023-02-24T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: false,
    duration: null,
    libraryId: 'library-id',
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.jpg',
    faces: [],
    exifInfo: {
      fileSizeInByte: 5000,
      exifImageHeight: 3840,
      exifImageWidth: 2160,
    } as Exif,
    duplicateId: null,
    isOffline: true,
    stackId: null,
    updateId: '42',
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),
  archived: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.jpg',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.jpg',
    faces: [],
    deletedAt: null,
    exifInfo: {
      fileSizeInByte: 5000,
      exifImageHeight: 3840,
      exifImageWidth: 2160,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    libraryId: null,
    stackId: null,
    updateId: '42',
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  external: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/data/user1/photo.jpg',
    checksum: Buffer.from('path hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    isExternal: true,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    libraryId: 'library-id',
    sharedLinks: [],
    originalFileName: 'asset-id.jpg',
    faces: [],
    deletedAt: null,
    exifInfo: {
      fileSizeInByte: 5000,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    updateId: '42',
    stackId: null,
    stack: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  image1: Object.freeze({
    id: 'asset-id-1',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.ext',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    deletedAt: null,
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    isExternal: false,
    sharedLinks: [],
    originalFileName: 'asset-id.ext',
    faces: [],
    exifInfo: {
      fileSizeInByte: 5000,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    updateId: '42',
    stackId: null,
    libraryId: null,
    stack: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  imageFrom2015: Object.freeze({
    id: 'asset-id-2015',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2015-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2015-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.ext',
    files,
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2015-02-23T05:06:29.716Z'),
    updatedAt: new Date('2015-02-23T05:06:29.716Z'),
    localDateTime: new Date('2015-02-23T05:06:29.716Z'),
    isFavorite: true,
    isExternal: false,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    updateId: 'foo',
    libraryId: null,
    stackId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.ext',
    faces: [],
    exifInfo: {
      fileSizeInByte: 5000,
    } as Exif,
    deletedAt: null,
    duplicateId: null,
    isOffline: false,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  video: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    originalFileName: 'asset-id.ext',
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.ext',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Video,
    files: [previewFile],
    thumbhash: null,
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    isExternal: false,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    faces: [],
    exifInfo: {
      fileSizeInByte: 100_000,
      exifImageHeight: 2160,
      exifImageWidth: 3840,
    } as Exif,
    deletedAt: null,
    duplicateId: null,
    isOffline: false,
    updateId: '42',
    libraryId: null,
    stackId: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  livePhotoMotionAsset: Object.freeze({
    status: AssetStatus.Active,
    id: fileStub.livePhotoMotion.uuid,
    originalPath: fileStub.livePhotoMotion.originalPath,
    ownerId: authStub.user1.user.id,
    type: AssetType.Video,
    fileModifiedAt: new Date('2022-06-19T23:41:36.910Z'),
    fileCreatedAt: new Date('2022-06-19T23:41:36.910Z'),
    exifInfo: {
      fileSizeInByte: 100_000,
      timeZone: `America/New_York`,
    },
    files: [] as AssetFile[],
    libraryId: null,
    visibility: AssetVisibility.Hidden,
    width: null,
    height: null,
    edits: [] as AssetEditActionItem[],
  } as MapAsset & { faces: AssetFace[]; files: AssetFile[]; exifInfo: Exif; edits: AssetEditActionItem[] }),

  livePhotoStillAsset: Object.freeze({
    id: 'live-photo-still-asset',
    status: AssetStatus.Active,
    originalPath: fileStub.livePhotoStill.originalPath,
    ownerId: authStub.user1.user.id,
    type: AssetType.Image,
    livePhotoVideoId: 'live-photo-motion-asset',
    fileModifiedAt: new Date('2022-06-19T23:41:36.910Z'),
    fileCreatedAt: new Date('2022-06-19T23:41:36.910Z'),
    exifInfo: {
      fileSizeInByte: 25_000,
      timeZone: `America/New_York`,
    },
    files,
    faces: [] as AssetFace[],
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [] as AssetEditActionItem[],
  } as MapAsset & { faces: AssetFace[]; files: AssetFile[]; edits: AssetEditActionItem[] }),

  livePhotoWithOriginalFileName: Object.freeze({
    id: 'live-photo-still-asset',
    status: AssetStatus.Active,
    originalPath: fileStub.livePhotoStill.originalPath,
    originalFileName: fileStub.livePhotoStill.originalName,
    ownerId: authStub.user1.user.id,
    type: AssetType.Image,
    livePhotoVideoId: 'live-photo-motion-asset',
    fileModifiedAt: new Date('2022-06-19T23:41:36.910Z'),
    fileCreatedAt: new Date('2022-06-19T23:41:36.910Z'),
    exifInfo: {
      fileSizeInByte: 25_000,
      timeZone: `America/New_York`,
    },
    files: [] as AssetFile[],
    libraryId: null,
    faces: [] as AssetFace[],
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [] as AssetEditActionItem[],
  } as MapAsset & { faces: AssetFace[]; files: AssetFile[]; edits: AssetEditActionItem[] }),

  withLocation: Object.freeze({
    id: 'asset-with-favorite-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-22T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-22T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    checksum: Buffer.from('file hash', 'utf8'),
    originalPath: '/original/path.ext',
    type: AssetType.Image,
    files: [previewFile],
    thumbhash: null,
    encodedVideoPath: null,
    createdAt: new Date('2023-02-22T05:06:29.716Z'),
    updatedAt: new Date('2023-02-22T05:06:29.716Z'),
    localDateTime: new Date('2020-12-31T23:59:00.000Z'),
    isFavorite: false,
    isExternal: false,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    updateId: 'foo',
    libraryId: null,
    stackId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.ext',
    faces: [],
    exifInfo: {
      latitude: 100,
      longitude: 100,
      fileSizeInByte: 23_456,
      city: 'test-city',
      state: 'test-state',
      country: 'test-country',
    } as Exif,
    deletedAt: null,
    duplicateId: null,
    isOffline: false,
    tags: [],
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  sidecar: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.ext',
    thumbhash: null,
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files: [previewFile, sidecarFileWithExt],
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    isExternal: false,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.ext',
    faces: [],
    deletedAt: null,
    duplicateId: null,
    isOffline: false,
    updateId: 'foo',
    libraryId: null,
    stackId: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  sidecarWithoutExt: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.ext',
    thumbhash: null,
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files: [previewFile, sidecarFileWithoutExt],
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    isExternal: false,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.ext',
    faces: [],
    deletedAt: null,
    duplicateId: null,
    isOffline: false,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  hasEncodedVideo: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    originalFileName: 'asset-id.ext',
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.ext',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Video,
    files: [previewFile],
    thumbhash: null,
    encodedVideoPath: '/encoded/video/path.mp4',
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    isExternal: false,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    faces: [],
    exifInfo: {
      fileSizeInByte: 100_000,
    } as Exif,
    deletedAt: null,
    duplicateId: null,
    isOffline: false,
    updateId: '42',
    libraryId: null,
    stackId: null,
    stack: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  hasFileExtension: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/data/user1/photo.jpg',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    isExternal: true,
    duration: null,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    libraryId: 'library-id',
    sharedLinks: [],
    originalFileName: 'photo.jpg',
    faces: [],
    deletedAt: null,
    exifInfo: {
      fileSizeInByte: 5000,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  imageDng: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.dng',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.dng',
    faces: [],
    deletedAt: null,
    exifInfo: {
      fileSizeInByte: 5000,
      profileDescription: 'Adobe RGB',
      bitsPerSample: 14,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    updateId: '42',
    libraryId: null,
    stackId: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),

  imageHif: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.hif',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.hif',
    faces: [],
    deletedAt: null,
    exifInfo: {
      fileSizeInByte: 5000,
      profileDescription: 'Adobe RGB',
      bitsPerSample: 14,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    updateId: '42',
    libraryId: null,
    stackId: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),
  panoramaTif: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.tif',
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    files,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2023-02-23T05:06:29.716Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.tif',
    faces: [],
    deletedAt: null,
    sidecarPath: null,
    exifInfo: {
      fileSizeInByte: 5000,
      projectionType: 'EQUIRECTANGULAR',
    } as Exif,
    duplicateId: null,
    isOffline: false,
    updateId: '42',
    libraryId: null,
    stackId: null,
    visibility: AssetVisibility.Timeline,
    width: null,
    height: null,
    edits: [],
  }),
  withCropEdit: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.jpg',
    files,
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2025-01-01T01:02:03.456Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    updateId: 'foo',
    libraryId: null,
    stackId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.jpg',
    faces: [],
    deletedAt: null,
    sidecarPath: null,
    exifInfo: {
      fileSizeInByte: 5000,
      exifImageHeight: 3840,
      exifImageWidth: 2160,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    stack: null,
    orientation: '',
    projectionType: null,
    height: 3840,
    width: 2160,
    visibility: AssetVisibility.Timeline,
    edits: [
      {
        action: AssetEditAction.Crop,
        parameters: {
          width: 1512,
          height: 1152,
          x: 216,
          y: 1512,
        },
      },
    ] as AssetEditActionItem[],
  }),
  withoutEdits: Object.freeze({
    id: 'asset-id',
    status: AssetStatus.Active,
    deviceAssetId: 'device-asset-id',
    fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'),
    fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'),
    owner: userStub.user1,
    ownerId: 'user-id',
    deviceId: 'device-id',
    originalPath: '/original/path.jpg',
    files: editedFiles,
    checksum: Buffer.from('file hash', 'utf8'),
    type: AssetType.Image,
    thumbhash: Buffer.from('blablabla', 'base64'),
    encodedVideoPath: null,
    createdAt: new Date('2023-02-23T05:06:29.716Z'),
    updatedAt: new Date('2023-02-23T05:06:29.716Z'),
    localDateTime: new Date('2025-01-01T01:02:03.456Z'),
    isFavorite: true,
    duration: null,
    isExternal: false,
    livePhotoVideo: null,
    livePhotoVideoId: null,
    updateId: 'foo',
    libraryId: null,
    stackId: null,
    sharedLinks: [],
    originalFileName: 'asset-id.jpg',
    faces: [],
    deletedAt: null,
    sidecarPath: null,
    exifInfo: {
      fileSizeInByte: 5000,
      exifImageHeight: 3840,
      exifImageWidth: 2160,
    } as Exif,
    duplicateId: null,
    isOffline: false,
    stack: null,
    orientation: '',
    projectionType: null,
    height: 3840,
    width: 2160,
    visibility: AssetVisibility.Timeline,
    edits: [],
  }),
};
