package io.sentry.android.core.internal.debugmeta

import android.content.Context
import android.content.res.AssetManager
import io.sentry.ILogger
import io.sentry.SentryOptions
import io.sentry.util.DebugMetaPropertiesApplier
import java.io.FileNotFoundException
import java.nio.charset.Charset
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever

class AssetsDebugMetaLoaderTest {
  class Fixture {
    val context = mock<Context>()
    val assets = mock<AssetManager>()
    val logger = mock<ILogger>()

    fun getSut(
      fileName: String = "sentry-debug-meta.properties",
      content: String? = null,
      throws: Boolean = false,
    ): AssetsDebugMetaLoader {
      if (content != null) {
        whenever(assets.open(fileName))
          .thenReturn(content.byteInputStream(Charset.defaultCharset()))
      }
      if (throws) {
        whenever(assets.open(fileName)).thenThrow(FileNotFoundException())
      }
      whenever(context.assets).thenReturn(assets)
      return AssetsDebugMetaLoader(context, logger)
    }
  }

  private val fixture = Fixture()

  @Test
  fun `reads from assets into properties and can be applied to options`() {
    val sut =
      fixture.getSut(
        content =
          """
          #Generated by sentry-maven-plugin
          #Wed May 17 15:33:34 CEST 2023
          io.sentry.ProguardUuids=34077988-a0e5-4839-9618-7400e1616d1b
          io.sentry.bundle-ids=88ba82db-cd26-4c09-8b31-21461d286b68
          io.sentry.build-tool=maven
          """
            .trimIndent()
      )

    val options = SentryOptions()

    assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.applyToOptions(options, it) }

    assertEquals(options.bundleIds, setOf("88ba82db-cd26-4c09-8b31-21461d286b68"))
    assertEquals(options.proguardUuid, "34077988-a0e5-4839-9618-7400e1616d1b")
  }

  @Test
  fun `reads multiple bundle IDs from assets into properties and can be applied to options`() {
    val sut =
      fixture.getSut(
        content =
          """
          #Generated by sentry-maven-plugin
          #Wed May 17 15:33:34 CEST 2023
          io.sentry.ProguardUuids=34077988-a0e5-4839-9618-7400e1616d1b
          io.sentry.bundle-ids=88ba82db-cd26-4c09-8b31-21461d286b68,8d11a44a-facd-46c1-a49b-87d256227101
          io.sentry.build-tool=maven
          """
            .trimIndent()
      )

    val options = SentryOptions()

    assertNotNull(sut.loadDebugMeta()) { DebugMetaPropertiesApplier.applyToOptions(options, it) }

    assertEquals(
      options.bundleIds,
      setOf("88ba82db-cd26-4c09-8b31-21461d286b68", "8d11a44a-facd-46c1-a49b-87d256227101"),
    )
    assertEquals(options.proguardUuid, "34077988-a0e5-4839-9618-7400e1616d1b")
  }

  @Test
  fun `when file does not exist, swallows exception and returns null`() {
    val sut = fixture.getSut(throws = true)

    assertNull(sut.loadDebugMeta())
  }
}
