package mobvista.dmp.datasource.id_mapping

import mobvista.dmp.common.MobvistaConstant.{allZero, andriodIdAll, andriodIdPtn, didPtn, imeiPtn, imeiPtnAll, ipPtn, md5Ptn}
import mobvista.dmp.datasource.id_mapping.Constant.{getDevId, parseUA, process}
import org.apache.commons.lang3.StringUtils
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.functions.lit
import org.apache.spark.sql.{Row, SparkSession}

/**
 * @package: mobvista.dmp.datasource.id_mapping
 * @author: wangjf
 * @date: 2021/11/30
 * @time: 7:51 下午
 * @email: jinfeng.wang@mobvista.com
 */
class ReYun extends EtlDeviceIdDaily {

  override def processData(date: String, i: Int, spark: SparkSession): RDD[(String, Row)] = {
    spark.udf.register("getDevId", getDevId _)
    spark.udf.register("parseUA", parseUA _)

    val year = date.substring(0, 4)
    val month = date.substring(4, 6)
    val day = date.substring(6, 8)

    val commonInput = "s3://mob-emr-test/reyun/dmp/onedata/dwd/dwd_device_ids_inc_daily"

    val tkioEventIosRDD = spark.read.orc(s"$commonInput/$year/$month/$day/tkio_event/ios")
    val abtestIosRDD = spark.read.orc(s"$commonInput/$year/$month/$day/abtest/ios")

    val tkioEventAdrRDD = spark.read.orc(s"$commonInput/$year/$month/$day/tkio_event/android")
    val abtestAdrRDD = spark.read.orc(s"$commonInput/$year/$month/$day/abtest/android")

    val iosDF = tkioEventIosRDD.union(abtestIosRDD)
      .withColumn("cnt", lit(1L))
      .rdd.map(row => {
      ("ios", parseIosRow(row))
    })
    val adrDF = tkioEventAdrRDD.union(abtestAdrRDD)
      .withColumn("cnt", lit(1L))
      .rdd.map(row => {
      ("android", parseAdrRow(row))
    })
    iosDF.union(adrDF)
  }

  def parseIosRow(row: Row): Row = {
    val idfa = row.getAs[String]("idfa")
    val idfv = row.getAs[String]("idfv")
    val pkg_name = row.getAs[String]("pkg_name")
    val sysId = ""
    val bkupIp = ""
    val xwho = ""
    val user_id = ""
    val country = "CN"
    val ip = row.getAs[String]("ip")
    val ua = row.getAs[String]("ua")
    val brand = row.getAs[String]("brand")
    val model = row.getAs[String]("model")
    val os_version = row.getAs[String]("os_version")
    val osv_upt = "0"
    val upt = "0"
    val network_type = row.getAs[String]("network_type")
    val cnt = row.getAs[Long]("cnt")

    val f_idfa = if (StringUtils.isNotBlank(idfa) && (idfa.matches(didPtn) && !idfa.matches(allZero) || idfa.matches(md5Ptn))) {
      idfa
    } else {
      ""
    }
    val f_idfv = if (StringUtils.isNotBlank(idfv) && (idfv.matches(didPtn) && !idfv.matches(allZero) || idfv.matches(md5Ptn))) {
      idfv
    } else {
      ""
    }
    val f_ip = if (StringUtils.isNotBlank(ip) && ip.matches(ipPtn)) {
      ip
    } else {
      ""
    }
    val f_ua = if (StringUtils.isNotBlank(ua)) {
      ua.trim
    } else {
      ""
    }
    val f_brand = if (StringUtils.isNotBlank(brand)) {
      brand.trim
    } else {
      ""
    }
    val f_model = if (StringUtils.isNotBlank(model)) {
      model.trim
    } else {
      ""
    }
    val f_osv = if (StringUtils.isNotBlank(os_version)) {
      os_version.trim
    } else {
      ""
    }
    val f_network_type = if (StringUtils.isNotBlank(network_type) && !network_type.equalsIgnoreCase("unknown")) {
      network_type.trim
    } else {
      ""
    }
    Row(f_idfa, f_idfv, pkg_name, sysId, bkupIp, xwho, user_id, country, f_ip, f_ua, f_brand, f_model, f_osv, osv_upt, upt, "", f_network_type, cnt)
  }

  def parseAdrRow(row: Row): Row = {
    val gaid = row.getAs[String]("gaid")
    val oaid = row.getAs[String]("oaid")
    val imei = row.getAs[String]("imei")
    val androidId = row.getAs[String]("android_id")
    val pkg_name = row.getAs[String]("pkg_name")
    val sysId = ""
    val bkupIp = ""
    val xwho = ""
    val user_id = ""
    val country = "CN"
    val ip = row.getAs[String]("ip")
    val ua = row.getAs[String]("ua")
    val brand = row.getAs[String]("brand")
    val model = row.getAs[String]("model")
    val os_version = row.getAs[String]("os_version")
    val osv_upt = "0"
    val upt = "0"
    val network_type = row.getAs[String]("network_type")
    val cnt = row.getAs[Long]("cnt")

    val f_imei = if (StringUtils.isNotBlank(imei) && (imei.matches(imeiPtn) && !imei.matches(imeiPtnAll) || imei.matches(md5Ptn))) {
      imei
    } else {
      ""
    }
    val f_androidId = if (StringUtils.isNotBlank(androidId) && (androidId.matches(andriodIdPtn) && !androidId.matches(andriodIdAll) || androidId.matches(md5Ptn))) {
      androidId
    } else {
      ""
    }
    val f_oaid = if (StringUtils.isNotBlank(oaid) && (oaid.length >= 16 && oaid.length <= 64 && !oaid.matches(allZero) || oaid.matches(md5Ptn))) {
      oaid
    } else {
      ""
    }
    val f_gaid = if (StringUtils.isNotBlank(gaid) && (gaid.matches(didPtn) && !gaid.matches(allZero) || gaid.matches(md5Ptn))) {
      gaid
    } else {
      ""
    }

    val f_ip = if (StringUtils.isNotBlank(ip) && ip.matches(ipPtn)) {
      ip
    } else {
      ""
    }
    val f_ua = if (StringUtils.isNotBlank(ua)) {
      ua.trim
    } else {
      ""
    }
    val f_brand = if (StringUtils.isNotBlank(brand)) {
      brand.trim
    } else {
      ""
    }
    val f_model = if (StringUtils.isNotBlank(model)) {
      model.trim
    } else {
      ""
    }
    val f_osv = if (StringUtils.isNotBlank(os_version)) {
      os_version.trim
    } else {
      ""
    }
    val f_network_type = if (StringUtils.isNotBlank(network_type) && !network_type.equalsIgnoreCase("unknown")) {
      network_type.trim
    } else {
      ""
    }
    Row(f_imei, f_androidId, pkg_name, f_oaid, f_gaid, sysId, bkupIp, xwho, user_id, country, f_ip, f_ua, f_brand, f_model, f_osv, osv_upt, upt, "", f_network_type, cnt)
  }
}

object ReYun {
  def main(args: Array[String]): Unit = {
    new ReYun().run(args)
  }
}