// `withReleaseSigning` config-plugin tests. Locks down the regex injection
// against the SDK 55 Expo Android template so future Expo upgrades that
// change the template shape surface as a single failing test rather than
// silent debug-key-signed release bundles.
//
// The plugin runs at `npx expo prebuild` time and patches the regenerated
// `android/app/build.gradle`; if the regexes stop matching, prebuild
// either falls through to the world-known debug key (catastrophic) or
// throws (good — explicit failure is recoverable).

const { injectReleaseSigning } = require('../plugins/withReleaseSigning')

// SDK 55 Expo Android template shape. Lifted verbatim from a freshly
// `npx expo prebuild`'d project — only the namespace and a handful of
// project-name placeholders are abridged.
const TEMPLATE = `apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"

android {
    ndkVersion rootProject.ext.ndkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    compileSdk rootProject.ext.compileSdkVersion

    namespace 'com.halflight.app'
    defaultConfig {
        applicationId 'com.halflight.app'
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.8.0"
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false)
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true)
        }
    }
}
`

describe('withReleaseSigning.injectReleaseSigning', () => {
  it('splices a signingConfigs.release block next to debug', () => {
    const out = injectReleaseSigning(TEMPLATE)
    // The release block lives inside signingConfigs alongside debug.
    expect(out).toMatch(/signingConfigs\s*\{[\s\S]*?debug\s*\{[\s\S]*?\}[\s\S]*?release\s*\{[\s\S]*?HALFLIGHT_UPLOAD_STORE_FILE/)
  })

  it('rewrites buildTypes.release.signingConfig to the conditional', () => {
    const out = injectReleaseSigning(TEMPLATE)
    expect(out).toContain(
      `signingConfig project.hasProperty('HALFLIGHT_UPLOAD_STORE_FILE') ? signingConfigs.release : signingConfigs.debug`
    )
  })

  it('preserves the debug buildType — its signingConfig signingConfigs.debug line stays untouched', () => {
    const out = injectReleaseSigning(TEMPLATE)
    // buildTypes.debug { signingConfig signingConfigs.debug } must remain so
    // `expo run:android` keeps signing dev builds with the debug key.
    expect(out).toMatch(/buildTypes\s*\{\s*debug\s*\{\s*signingConfig\s+signingConfigs\.debug\s*\}/)
  })

  it('replaces exactly one occurrence of `signingConfig signingConfigs.debug` (the release one)', () => {
    const before = (TEMPLATE.match(/signingConfig\s+signingConfigs\.debug/g) ?? []).length
    const after = (
      injectReleaseSigning(TEMPLATE).match(/signingConfig\s+signingConfigs\.debug/g) ?? []
    ).length
    // Template has 2: one in buildTypes.debug, one in buildTypes.release.
    // After injection, only buildTypes.debug's reference remains.
    expect(before).toBe(2)
    expect(after).toBe(1)
  })

  it('is idempotent — running twice on the same input produces no second injection', () => {
    const once = injectReleaseSigning(TEMPLATE)
    const twice = injectReleaseSigning(once)
    expect(twice).toBe(once)
  })

  it('preserves the rest of the release buildType (proguard, shrinkResources, …)', () => {
    const out = injectReleaseSigning(TEMPLATE)
    expect(out).toContain('minifyEnabled enableProguardInReleaseBuilds')
    expect(out).toContain('proguardFiles getDefaultProguardFile')
    expect(out).toContain('shrinkResources')
  })

  it('throws with a clear message when signingConfigs.debug is missing (template drift)', () => {
    const broken = TEMPLATE.replace(/signingConfigs\s*\{[\s\S]*?\n    \}/, '')
    expect(() => injectReleaseSigning(broken)).toThrow(/signingConfigs\.debug/)
  })

  it('throws with a clear message when buildTypes.release is missing (template drift)', () => {
    const broken = TEMPLATE.replace(
      /release\s*\{[\s\S]*?\n        \}/,
      'release { /* removed */ }'
    )
    expect(() => injectReleaseSigning(broken)).toThrow(/buildTypes\.release/)
  })
})
