const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY, 10) || 10

const minimist = require('minimist')

const { waitForDb } = require('../app/src/infrastructure/mongodb')
const ChatApiHandler = require('../app/src/Features/Chat/ChatApiHandler')
const DocstoreManager = require('../app/src/Features/Docstore/DocstoreManager')
const DocumentUpdaterHandler = require('../app/src/Features/DocumentUpdater/DocumentUpdaterHandler')
const { promiseMapWithLimit } = require('../app/src/util/promises')

/**
 * Remove doc comment ranges that are "orphaned" as they do have matching chat
 * threads. This can happen when adding comments and the HTTP request fails, but
 * the ShareJS op succeeded (eventually). See https://github.com/overleaf/internal/issues/3425
 * for more detail.
 */
async function main() {
  await waitForDb()

  const argv = minimist(process.argv.slice(2))
  const { projectId, docId } = argv

  const threads = await ChatApiHandler.promises.getThreads(projectId)
  const threadIds = Object.keys(threads)

  const doc = await DocstoreManager.promises.getDoc(projectId, docId)
  const comments = doc.ranges.comments

  const orphanedCommentIds = comments.filter(comment => {
    const commentThreadId = comment.op.t
    return !threadIds.includes(commentThreadId)
  })

  await promiseMapWithLimit(
    WRITE_CONCURRENCY,
    orphanedCommentIds,
    async comment => {
      await DocumentUpdaterHandler.promises.deleteThread(
        projectId,
        docId,
        comment.op.t
      )
    }
  )

  await DocumentUpdaterHandler.promises.flushDocToMongo(projectId, docId)
}

main()
  .then(() => {
    console.log('Done.')
    process.exit(0)
  })
  .catch(error => {
    console.error({ error })
    process.exit(1)
  })
