/*
 * Copyright 2023 Signal Messenger, LLC
 * SPDX-License-Identifier: AGPL-3.0-only
 */

package org.thoughtcrime.securesms.backup.v2.processor

import org.signal.archive.proto.Chat
import org.signal.archive.proto.Frame
import org.signal.archive.stream.BackupFrameEmitter
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.backup.v2.ExportState
import org.thoughtcrime.securesms.backup.v2.ImportSkips
import org.thoughtcrime.securesms.backup.v2.ImportState
import org.thoughtcrime.securesms.backup.v2.database.getThreadsForBackup
import org.thoughtcrime.securesms.backup.v2.importer.ChatArchiveImporter
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.recipients.RecipientId

/**
 * Handles importing/exporting [Chat] frames for an archive.
 */
object ChatArchiveProcessor {
  val TAG = Log.tag(ChatArchiveProcessor::class.java)

  fun export(db: SignalDatabase, exportState: ExportState, emitter: BackupFrameEmitter) {
    db.threadTable.getThreadsForBackup(db, exportState, includeImageWallpapers = true).use { reader ->
      for (chat in reader) {
        if (exportState.recipientIds.contains(chat.recipientId)) {
          exportState.threadIds.add(chat.id)
          exportState.threadIdToRecipientId[chat.id] = chat.recipientId
          emitter.emit(Frame(chat = chat))
        } else {
          Log.w(TAG, "dropping thread for deleted recipient ${chat.recipientId}")
        }
      }
    }
  }

  fun import(chat: Chat, importState: ImportState) {
    val recipientId: RecipientId? = importState.remoteToLocalRecipientId[chat.recipientId]
    if (recipientId == null) {
      Log.w(TAG, ImportSkips.missingChatRecipient(chat.id))
      return
    }

    val threadId = ChatArchiveImporter.import(chat, recipientId, importState)
    if (threadId == null) {
      Log.w(TAG, ImportSkips.failedToCreateChat())
      return
    }

    importState.chatIdToLocalRecipientId[chat.id] = recipientId
    importState.chatIdToLocalThreadId[chat.id] = threadId
    importState.chatIdToBackupRecipientId[chat.id] = chat.recipientId
    importState.recipientIdToLocalThreadId[recipientId] = threadId
  }
}
