import groovy.json.JsonOutput
import groovy.json.JsonSlurper

String[] fileNames = ["app.json", "app.config.js"]
String fileName = null
String jsonRoot = "react-native-tapsell-mediation"
String jsonRaw = "TAPSELL_MEDIATION_JSON_RAW"

File configFile = null
File parentDir = rootProject.projectDir

for (int i = 0; i <= 3; i++) {
  if (parentDir == null) break
  parentDir = parentDir.parentFile
  if (parentDir != null) {
    configFile = new File(parentDir, fileNames[0])
    if (configFile.exists()) {
      fileName = fileNames[0]
      break
    }
    else {
      configFile = new File(parentDir, fileNames[1])
      if (configFile.exists()) {
        fileName = fileNames[0]
        break
      }
    }
  }
}

if (configFile != null && configFile.exists()) {
  rootProject.logger.info ":${project.name} ${fileName} found at ${configFile.toString()}"
  Object json = null

  try {
    // On windows, we need to escape path separators in the path before exec'ing shell
    def configFileAbsolutePath = configFile.absolutePath
    if (System.properties['os.name'].toLowerCase().contains('windows')) {
        configFileAbsolutePath = configFileAbsolutePath.replace("\\", "\\\\")
    }
    // rootProject.logger.warn "have a path of ${configFileAbsolutePath}"

    // The config may be either in Expo javascript (app.config.js) or JSON (app.json)
    // If it is configured in Expo javascript, requiring it will generate a config
    // If it is configured in JSON, requiring it will also generate the config
    // So, use node to pull in the config file to get us a JSON string for either case
    def configOutput = new StringBuffer();
    def configReadProc = [
      "node",
      "-e",
      "console.log(JSON.stringify(require('${configFileAbsolutePath}')));"
    ]
    .execute(null, projectDir)
    configReadProc.waitForProcessOutput(configOutput, System.err)
    configOutput = configOutput.toString().trim()
    // rootProject.logger.warn "got configOutput of ${configOutput.toString()}"

    if (configOutput && !configOutput.isEmpty()) {
      json = new JsonSlurper().parseText(configOutput)
    } else {
      throw new Exception(":${project.name} received empty output while parsing ${configFile} found at ${configFile.toString()}.")
    }
  } catch (Exception ignored) {
    rootProject.logger.warn ":${project.name} failed to parse ${configFile} found at ${configFile.toString()}."
    rootProject.logger.warn ignored.toString()
  }

  if (json && json[jsonRoot]) {
    String jsonStr = JsonOutput.toJson(JsonOutput.toJson(json[jsonRoot]))

    rootProject.ext.tapsellMediationJson = [
      raw: json[jsonRoot],
      isFlagEnabled: { key, defaultValue ->
        if (json[jsonRoot] == null || json[jsonRoot][key] == null) return defaultValue
        return json[jsonRoot][key] == true ? true : false
      },
      getStringValue: { key, defaultValue ->
        if (json[jsonRoot] == null) return defaultValue
        return json[jsonRoot][key] ? json[jsonRoot][key] : defaultValue
      }
    ]

    rootProject.logger.info ":${project.name} found ${jsonRoot} json root in ${fileName}, creating app build config"
    android {
      defaultConfig {
        buildConfigField "String", jsonRaw, jsonStr
      }
    }
  } else {
    rootProject.ext.tapsellJson = false
    rootProject.logger.info ":${project.name} ${fileName} found with no ${jsonRoot} config, skipping"
    android {
      defaultConfig {
        buildConfigField "String", jsonRaw, '"{}"'
      }
    }
  }
} else {
  rootProject.ext.tapsellMediationJson = false
  rootProject.logger.info ":${project.name} no ${fileName} found, skipping"
  android {
    defaultConfig {
      buildConfigField "String", jsonRaw, '"{}"'
    }
  }
}
