package mobvista.dmp.datasource.rtdmp

import com.alibaba.fastjson.{JSON, JSONArray, JSONObject}
import com.datastax.oss.driver.api.core.CqlSession
import com.datastax.oss.driver.api.core.cql.ResultSet
import com.datastax.spark.connector.cql.CassandraConnector
import mobvista.dmp.common.MobvistaConstant
import mobvista.dmp.datasource.rtdmp.Constant.{AudienceInfo, AudienceRegion, DmpDeviceRegin, NewAudienceInfo}
import mobvista.dmp.util.cassandra.CassandraUtils
import mobvista.dmp.util.{DateUtil, JdbcUtils}
import org.apache.commons.lang3.StringUtils
import org.apache.hadoop.io.Text
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.{StringType, StructField, StructType}

import java.util.StringJoiner
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
import scala.collection.mutable.ArrayBuffer
import scala.collection.{immutable, mutable}

/**
 * @package: mobvista.dmp.datasource.rtdmp
 * @author: wangjf
 * @date: 2020/7/13
 * @time: 11:22 上午
 * @email: jinfeng.wang@mobvista.com
 * @phone: 152-1062-7698
 */
object Logic {

  def getResultFeature(session: CqlSession, iterator: Iterator[Row]): Iterator[AudienceInfo] = {
    val sql =
      """
        |select audience_data from rtdmp.audience_info where devid = '@devid'
        |""".stripMargin

    val res = new ArrayBuffer[AudienceInfo]()
    iterator.foreach(row => {
      val devId = row.getAs[String](0)
      val audience_data = row.getAs[String](1)
      val query_sql = sql.replace("@devid", devId)
      val resultStage = CassandraUtils.query(session, query_sql)
      val old_audience_data = if (resultStage.get() != null) {
        MobvistaConstant.String2JSONObject(resultStage.get().getString(0)).toJSONString
      } else {
        new JSONObject().toJSONString
      }
      res.add(AudienceInfo(devId, audience_data, old_audience_data))
    })
    res.iterator()
  }

  def parseAudienceInfo(audienceInfos: Iterator[Constant.AudienceInfo], expire_time: String): Iterator[Constant.NewAudienceInfo] = {
    val array = new ArrayBuffer[NewAudienceInfo]()
    audienceInfos.foreach(audienceInfo => {
      val devId = audienceInfo.devid
      //  val update_time = audienceInfo.update_time
      val audience_data = audienceInfo.audience_data
      val old_audience_data = audienceInfo.old_audience_data
      val new_json = MobvistaConstant.String2JSONObject(audience_data)
      //  对旧的 audience_data 数据进行过滤，筛选出满足条件（audienceId 对应的 update_date 没有过期）的 audienceId 映射关系
      val old_json = JSON.toJSON(MobvistaConstant.String2JSONObject(old_audience_data).asInstanceOf[java.util.Map[String, String]]
        .retain((_, v) => v.compareTo(expire_time) > 0).toMap.asJava).asInstanceOf[JSONObject]
      new_json.keySet().foreach(k => {
        var flag = true
        val audienceId =
          if (k.toLong < 0) { //  判断新的人群包中 audienceId 是否小于 0，设置标识符 flag = false，并将 audienceId * (-1)，转为正确的 audienceId
            flag = false
            ((-1) * k.toLong).toString
          } else {
            k
          }
        if (old_json.containsKey(audienceId) && !flag) { //  如果旧的人群包中 audienceId数组中 包含 audienceId 且标识符 flag = false，则删除该 audienceId
          old_json.remove(audienceId)
        } else { //  否则更新 audienceId 对应的 update_date 信息
          old_json.put(audienceId, new_json.getString(audienceId))
        }
      })
      array.add(Constant.NewAudienceInfo(devId, "", old_json.toJSONString, ""))
    })
    array.iterator
  }

  def writeResultV2(connector: CassandraConnector, iterator: Iterator[NewAudienceInfo]): Iterator[AudienceRegion] = {
    /*
    val sql =
      """
        |SELECT dev_type, region FROM rtdmp.recent_device_region WHERE devid = '@devid'
        |""".stripMargin

    val res = new CopyOnWriteArrayList[AudienceRegion]()

    iterator.foreach(audienceInfo => {
      val session = connector.openSession()
      val devId = audienceInfo.devid
      val jsonObject = new JSONObject()
      jsonObject.put("devid", audienceInfo.devid)
      val audienceSet = new mutable.HashSet[Int]()
      MobvistaConstant.String2JSONObject(audienceInfo.audience_data).keySet().foreach(k => {
        audienceSet.add(Integer.parseInt(k))
      })
      jsonObject.put("audience_id", audienceSet.asJava)
      val query_sql = sql.replace("@devid", devId)
      val result = parseRegionV2(CassandraUtils.query(session, query_sql).get())
      if (StringUtils.isNotBlank(result._1)) {
        jsonObject.put("dev_type", result._1)
      }
      session.close()
      res.add(AudienceRegion(jsonObject.toJSONString, result._2))
    })
    */
    val res = new ArrayBuffer[AudienceRegion]()

    iterator.foreach(audienceInfo => {
      val jsonObject = new JSONObject()
      jsonObject.put("devid", audienceInfo.devid)
      val audienceSet = new mutable.HashSet[Int]()
      MobvistaConstant.String2JSONObject(audienceInfo.audience_data).keySet().foreach(k => {
        audienceSet.add(Integer.parseInt(k))
      })
      jsonObject.put("audience_id", audienceSet.asJava)
      res.add(AudienceRegion(jsonObject.toJSONString, mutable.WrappedArray.empty[String]))
    })
    res.iterator()
  }

  def parseRegionV2(row: com.datastax.oss.driver.api.core.cql.Row): (String, mutable.WrappedArray[String]) = {
    val install_region =
      if (row != null) {
        val region = row.getObject("region").asInstanceOf[java.util.Set[String]]
        val dev_type = row.getString("dev_type")
        region.retain(r => {
          regionArray.contains(r)
        })
        if (region.nonEmpty) {
          (dev_type, mutable.WrappedArray.make[String](region.toArray))
        } else {
          (dev_type, regionArray)
        }
      } else {
        ("", regionArray)
      }
    install_region
  }

  def writeResult(connector: CassandraConnector, iterator: Iterator[NewAudienceInfo]): Iterator[AudienceRegion] = {

    val sql =
      """
        |SELECT dev_type, region, install_list FROM rtdmp.recent_device_info WHERE devid = '@devid'
        |""".stripMargin

    val res = new ArrayBuffer[AudienceRegion]()

    iterator.foreach(audienceInfo => {
      val session = connector.openSession()
      val devId = audienceInfo.devid
      val jsonObject = new JSONObject()
      jsonObject.put("devid", audienceInfo.devid)
      val audienceSet = new mutable.HashSet[Int]()
      MobvistaConstant.String2JSONObject(audienceInfo.audience_data).keySet().foreach(k => {
        audienceSet.add(Integer.parseInt(k))
      })
      jsonObject.put("audience_id", audienceSet.asJava)
      val query_sql = sql.replace("@devid", devId)
      val result = parseInstallRegion(CassandraUtils.query(session, query_sql).get())
      if (StringUtils.isNotBlank(result._1)) {
        jsonObject.put("dev_type", result._1)
      }
      if (result._2.nonEmpty) {
        jsonObject.put("install_list", result._2)
      }
      session.close()
      res.add(AudienceRegion(jsonObject.toJSONString, result._3))
    })
    res.iterator()
  }

  def parseInstallRegion(row: com.datastax.oss.driver.api.core.cql.Row): (String, JSONObject, mutable.WrappedArray[String]) = {
    val install_region =
      if (row != null) {
        val region = row.getObject("region").asInstanceOf[java.util.Set[String]]
        val install_list = MobvistaConstant.String2JSONObject(row.getString("install_list"))
        val dev_type = row.getString("dev_type")
        region.retain(r => {
          regionArray.contains(r)
        })
        if (region.nonEmpty) {
          (dev_type, install_list, mutable.WrappedArray.make[String](region.toArray))
        } else {
          (dev_type, install_list, regionArray)
        }
      } else {
        ("", new JSONObject(), regionArray)
      }
    install_region
  }


  def parseQueryRegion(result: ResultSet): (String, JSONObject, mutable.WrappedArray[String]) = {
    val install_region =
      if (result.nonEmpty) {
        val row = result.one()
        val region = row.getObject("region").asInstanceOf[java.util.Set[String]]
        val install_list = MobvistaConstant.String2JSONObject(row.getString("install_list"))
        val dev_type = row.getString("dev_type")
        region.retain(r => {
          regionArray.contains(r)
        })
        if (region.nonEmpty) {
          (dev_type, install_list, mutable.WrappedArray.make[String](region.toArray))
        } else {
          (dev_type, install_list, regionArray)
        }
      } else {
        ("", new JSONObject(), regionArray)
      }
    install_region
  }

  val regionArray: mutable.WrappedArray[String] = mutable.WrappedArray.make(mutable.Set("cn", "virginia", "seoul", "tokyo", "frankfurt", "singapore").toArray)

  def parseResult(output: String, trueId: immutable.Set[Integer], falseId: immutable.Set[Integer], iterator: Iterator[Row]): Iterator[(Text, Text)] = {
    val array = new ArrayBuffer[(Text, Text)]()
    iterator.foreach(it => {
      val audience_info = it.getAs[String]("audience_info")
      val jsonObject = MobvistaConstant.String2JSONObject(audience_info)
      val devid = jsonObject.getString("devid")
      val audience_id = JSON.parseArray(jsonObject.getJSONArray("audience_id").toJSONString, classOf[Integer]).toSet
      if (((audience_id -- falseId) & trueId).nonEmpty) {
        val newJSON = new JSONObject()
        newJSON.put("devid", devid)
        newJSON.put("audience_id", ((audience_id -- falseId) & trueId).asJava)
        val regionSet = it.getAs("region").asInstanceOf[mutable.WrappedArray[String]]
        for (region <- regionSet) {
          array.add((new Text(output + "/" + region), new Text(newJSON.toJSONString)))
        }
      }
    })
    array.iterator
  }

  def mergeRegionPartition(before_date: String, tuples: Iterator[(String, (Option[(String, String, String)], Option[(String, String, String, String, String)]))]): Iterator[DmpDeviceRegin] = {
    val array = new ArrayBuffer[DmpDeviceRegin]()
    tuples.foreach(t => {
      val deviceId = t._1
      val dailyOpt = t._2._1
      val allOpt = t._2._2
      var device_type = ""
      var platform = ""
      var region = ""
      var update_date = ""
      var publish_date = ""
      var tag = 0
      if (allOpt.nonEmpty && dailyOpt.nonEmpty) {
        device_type = dailyOpt.get._1
        platform = dailyOpt.get._2
        update_date = before_date
        val daily_region = dailyOpt.get._3
        val all_region = allOpt.get._3

        region = parseRegion(daily_region + "," + all_region)

        if (check_region(all_region, daily_region)) {
          tag = 1
          publish_date = before_date
        } else {
          val pub_day = (DateUtil.parse(before_date, "yyyyMMdd").getTime - DateUtil.parse(allOpt.get._5, "yyyyMMdd").getTime) / (1000 * 3600 * 24)
          if (pub_day >= 6) {
            tag = 1
            publish_date = before_date
          } else {
            tag = 0
            publish_date = allOpt.get._5
          }
        }
      } else if (allOpt.nonEmpty && dailyOpt.isEmpty) {
        device_type = allOpt.get._1
        platform = allOpt.get._2
        region = allOpt.get._3
        update_date = allOpt.get._4
        val pub_day = (DateUtil.parse(before_date, "yyyyMMdd").getTime - DateUtil.parse(allOpt.get._5, "yyyyMMdd").getTime) / (1000 * 3600 * 24)
        if (pub_day >= 6) {
          tag = 1
          publish_date = before_date
        } else {
          tag = 0
          publish_date = allOpt.get._5
        }
      } else {
        device_type = dailyOpt.get._1
        platform = dailyOpt.get._2
        update_date = before_date
        publish_date = before_date
        region = dailyOpt.get._3
        tag = 1
      }
      val dmpDeviceRegin = DmpDeviceRegin(deviceId, device_type, platform, region, update_date, publish_date, tag)
      array.add(dmpDeviceRegin)
    })
    array.iterator
  }

  def check_tag(flag: Boolean, update_date: String, publish_date: String): Int = {
    val days = (DateUtil.parse(update_date, "yyyyMMdd").getTime - DateUtil.parse(publish_date, "yyyyMMdd").getTime) / (1000 * 3600 * 24)
    if (flag || days >= 6) {
      1
    } else {
      0
    }
  }

  def check_publish(flag: Boolean, update_date: String, publish_date: String): String = {
    val days = (DateUtil.parse(update_date, "yyyyMMdd").getTime - DateUtil.parse(publish_date, "yyyyMMdd").getTime) / (1000 * 3600 * 24)
    if (flag || days >= 6) {
      update_date
    } else {
      publish_date
    }
  }

  def check_region(all_region: String, daily_region: String): Boolean = {
    val all_set = all_region.split(",", -1).toSet
    val daily_set = if (StringUtils.isNotBlank(daily_region)) {
      daily_region.split(",", -1).toSet
    } else {
      Set.empty[String]
    }
    val set = daily_set.diff(all_set)
    set.nonEmpty
  }

  def isDeviceMd5(device_id: String): Boolean = {
    if (device_id.matches(MobvistaConstant.md5Ptn)) {
      true
    } else {
      false
    }
  }

  def schema: StructType = {
    StructType(StructField("device_id", StringType) ::
      StructField("device_type", StringType) ::
      StructField("platform", StringType) ::
      StructField("region", StringType) :: Nil)
  }

  def parseToStr(re: String): String = {
    re.replace("[", "").replace("]", "").replace("\"", "")
  }

  def parseRegion(regions: String): String = {
    regions.split(",", -1).toSet.mkString(",")
  }

  def match_device_type(device_type: String): Int = {
    device_type match {
      case "imei" =>
        1
      case "idfa" =>
        2
      case "gaid" =>
        3
      case "oaid" =>
        4
      case "android_id" | "androidid" =>
        5
      case "imeimd5" | "imei_md5" =>
        6
      case "idfamd5" | "idfa_md5" =>
        7
      case "gaidmd5" | "gaid_md5" =>
        8
      case "oaidmd5" | "oaid_md5" =>
        9
      case "androididmd5" | "androidid_md5" =>
        10
      case "idfv" =>
        11
      case "sysid" =>
        12
      case _ =>
        0
    }
  }

  def processUpload(output: String, portalMap: Iterator[(String, (String, String))]): JSONArray = {
    val jsonArray = new JSONArray()
    println("portalMap -->> " + portalMap.size)
    for (m <- portalMap) {
      println("m -->> " + m)
      val jsonObject = new JSONObject()
      val platform = if (m._2._2.equals("ios")) {
        2
      } else {
        1
      }
      val match_device_type = Logic.match_device_type(m._2._1)
      jsonObject.put("s3_path", s"$output/${m._1}")
      jsonObject.put("platform", platform)
      jsonObject.put("match_device_type", match_device_type)
      jsonObject.put("audience_type", 2)
      jsonObject.put("data_update_method", 2)
      jsonObject.put("audience_name", m._1)
      jsonObject.put("status", 1)
      jsonArray.add(jsonObject)
      println("jsonObject -->> " + jsonObject)
    }
    println("jsonArray -->> " + jsonArray)
    jsonArray
  }

  def getAudienceInfo(business: String): mutable.HashMap[String, Int] = {
    val map = new mutable.HashMap[String, Int]
    val jdbcUtils = new JdbcUtils
    val result = jdbcUtils.query(s"SELECT package_name, audience_id FROM dmp.rtdmp_audience_info WHERE business = '$business'")
    while (result.next()) {
      val package_name = result.getString("package_name")
      val audience_id = result.getInt("audience_id")
      map.put(package_name, audience_id)
    }
    map
  }

  def getForactivationIdSet(foractivation: Int): mutable.Set[Integer] = {
    val set = new mutable.HashSet[Integer]
    val jdbcUtils = new JdbcUtils
    val result = jdbcUtils.query(s"SELECT audience_id FROM dmp.rtdmp_audience_info WHERE foractivation = $foractivation")
    while (result.next()) {
      val audience_id = result.getInt("audience_id")
      set.add(audience_id)
    }
    set
  }

  def getAudienceMap(pkgSet: mutable.HashSet[String]): mutable.HashMap[String, Int] = {
    val map = new mutable.HashMap[String, Int]
    pkgSet.foreach(pkg => {
      val id = ServerUtil.query(pkg)
      if (id > 0) {
        map.put(pkg, id)
      }
    })
    map
  }

  def writeAudienceInfo(business: String, map: mutable.HashMap[String, Int]): Boolean = {
    val values = new StringJoiner(",")
    map.foreach(kv => {
      values.add(s"('$business','${kv._1}',${kv._2})")
    })
    println(s"values -->> $values")
    if (StringUtils.isNotBlank(values.toString)) {
      val insertSql =
        s"""
           |REPLACE INTO dmp.rtdmp_audience_info(business, package_name, audience_id) VALUES $values
           |""".stripMargin
      val jdbcUtils = new JdbcUtils
      println(insertSql)
      jdbcUtils.update(insertSql)
    } else {
      true
    }
  }

  def putMap(): mutable.HashMap[String, Int] = {
    val map = new mutable.HashMap[String, Int]()
    map.put("com.taobao.foractivation.184147", 7)
    map.put("com.taobao.foractivation.149652", 8)
    map.put("com.taobao.foractivation.149655", 9)
    map.put("com.taobao.foractivation.149649", 10)
    map.put("com.taobao.foractivation.184287", 11)
    map.put("com.taobao.foractivation.149654", 12)
    map.put("com.taobao.foractivation.184289", 13)
    map.put("com.taobao.foractivation.172393", 14)
    map.put("com.taobao.foractivation.188844", 15)
    map.put("com.taobao.foractivation.149650", 16)
    map.put("com.taobao.foractivation.149647", 17)
    map.put("com.taobao.foractivation.149656", 18)
    map.put("com.taobao.foractivation", 19)
    map.put("com.taobao.foractivation.149653", 108)
    map.put("com.taobao.foractivation.219343", 109)
    map.put("202005219343", 110)
    map.put("com.taobao.foractivation.219809", 111)
    map.put("202005219809", 112)
    map.put("com.taobao.taobao_oppo", 115)
    map.put("com.taobao.foractivation.204543", 122)
    map.put("com.taobao.foractivation.227229", 123)
    map.put("com.taobao.foractivation.188844_oppo", 180)
    map.put("com.taobao.foractivation.227229_oppo", 181)
    map.put("com.taobao.foractivation.204543_oppo", 182)
    map.put("com.eg.android.AlipayGphone_oppo", 187)
    map.put("com.ucmobile_oppo", 190)
    map.put("com.taobao.taobao_btop", 196)
    map.put("com.uc.foractivation.d3f521", 207)
    map.put("com.uc.foractivation.4b5a58", 208)
    map.put("com.uc.foractivation.223a2a", 209)
    map.put("com.uc.foractivation.bf7722", 210)
    map.put("com.uc.foractivation.33c777", 211)
    map.put("com.uc.foractivation.304fcd", 212)
    map.put("com.uc.foractivation_imei", 213)
    map.put("com.uc.foractivation_oaid", 214)
    map.put("com.uc.notforactivation_imei", 215)
    map.put("com.uc.notforactivation_oaid", 216)
    map.put("com.iqiyi.foractivation", 217)
    map.put("com.qiyi.video_oppo", 218)
    map.put("com.taobao.foractivation.204543_oaid", 237)
    map.put("com.taobao.foractivation.227229_oaid", 238)
    map.put("com.taobao.taobao_notinstall_oppo", 281)
    map.put("com.taobao.foractivation.249582_oaid", 333)
    map.put("com.taobao.foractivation.241357_oaid", 334)
    map.put("com.taobao.foractivation.249582", 335)
    map.put("com.taobao.foractivation.241357", 336)
    map.put("com.taobao.foractivation.252594", 337)
    map.put("com.taobao.foractivation.251827", 338)
    map.put("com.taobao.foractivation.252594_oaid", 339)
    map.put("com.taobao.foractivation.251827_oaid", 340)
    map.put("com.taobao.foractivation.254029_oaid", 343)
    map.put("com.taobao.foractivation.254029", 344)
    map.put("com.taobao.foractivation.iqyi_227229", 349)
    map.put("com.taobao.foractivation.iqyi_227229_oaid", 350)
    map.put("com.alipay.foracquisition_L00002", 352)
    map.put("com.alipay.notforacquisition", 353)
    map.put("com.alipay.foracquisition", 354)
    map.put("com.alipay.foractivation_L00016", 355)
    map.put("com.alipay.foractivation", 356)
    map.put("com.alipay.notforactivation", 357)
    map.put("com.alipay.foractivation_L00009", 358)
    map.put("com.alipay.foractivation_L00008", 359)
    map.put("com.alipay.foractivation_L00005", 360)
    map.put("com.eg.android.AlipayGphone_bes", 364)
    map.put("com.youku.phone_notinstall_oppo", 368)
    map.put("com.taobao.foractivation.254343", 374)
    map.put("com.taobao.foractivation.256294", 375)
    map.put("com.taobao.foractivation.257904", 376)
    map.put("com.taobao.foractivation.254944", 377)
    map.put("com.taobao.foractivation.257904_oaid", 380)
    map.put("com.taobao.foractivation.254944_oaid", 381)
    map.put("com.taobao.foractivation.254343_oaid", 382)
    map.put("com.taobao.foractivation.256294_oaid", 383)
    map.put("com.meituan.itakeaway_oppo", 386)
    map.put("com.sankuai.meituan_oppo", 387)
    map.put("202005227229", 388)
    map.put("202005260935", 389)
    map.put("com.taobao.foractivation.260935", 390)
    map.put("com.taobao.foractivation.260951", 391)
    map.put("202005260951", 392)
    map.put("com.youku.foracquisition_oaid", 393)
    map.put("com.youku.foracquisition_imei", 394)
    map.put("com.taobao.foractivation.260935_oaid", 395)
    map.put("com.taobao.foractivation.260951_oaid", 396)
    map.put("com.taobao.foractivation.261865_oaid", 405)
    map.put("com.taobao.foractivation.261865", 406)
    map.put("202005261865", 407)
    map
  }

  def processToRegion(ext_data: String): mutable.WrappedArray[String] = {
    val regionSet = new mutable.HashSet[String]()
    val jsonObject = MobvistaConstant.String2JSONObject(ext_data)
    if (jsonObject.containsKey("dsp") && jsonObject.getJSONObject("dsp").containsKey("region")) {
      jsonObject.getJSONObject("dsp").getJSONArray("region").foreach(r => {
        if (r != null && StringUtils.isNotBlank(r.toString)) {
          regionSet.add(r.toString)
        }
      })
    }
    if (jsonObject.containsKey("m") && jsonObject.getJSONObject("m").containsKey("region")) {
      jsonObject.getJSONObject("m").getJSONArray("region").foreach(r => {
        if (r != null && StringUtils.isNotBlank(r.toString)) {
          regionSet.add(r.toString)
        }
      })
    }
    mutable.WrappedArray.make(regionSet.toArray)
  }

  def mapFunction(audienceInfo: AudienceInfo, expire_time: String): NewAudienceInfo = {
    val devId = audienceInfo.devid
    //  val update_time = audienceInfo.update_time
    val audience_data = audienceInfo.audience_data
    val old_audience_data = audienceInfo.old_audience_data
    val new_json = MobvistaConstant.String2JSONObject(audience_data)
    //  对旧的 audience_data 数据进行过滤，筛选出满足条件（audienceId 对应的 update_date 没有过期）的 audienceId 映射关系
    val old_json = JSON.toJSON(MobvistaConstant.String2JSONObject(old_audience_data).asInstanceOf[java.util.Map[String, String]]
      .retain((_, v) => v.compareTo(expire_time) > 0).toMap.asJava).asInstanceOf[JSONObject]
    new_json.keySet().foreach(k => {
      var flag = true
      val audienceId =
        if (k.toLong < 0) { //  判断新的人群包中 audienceId 是否小于 0，设置标识符 flag = false，并将 audienceId * (-1)，转为正确的 audienceId
          flag = false
          ((-1) * k.toLong).toString
        } else {
          k
        }
      if (old_json.containsKey(audienceId) && !flag) { //  如果旧的人群包中 audienceId数组中 包含 audienceId 且标识符 flag = false，则删除该 audienceId
        old_json.remove(audienceId)
      } else { //  否则更新 audienceId 对应的 update_date 信息
        old_json.put(audienceId, new_json.getString(audienceId))
      }
    })
    NewAudienceInfo(devId, "", old_json.toJSONString, "")
  }

  def getDevType(device_type: String): String = {
    device_type match {
      case "imeimd5" | "imei_md5" => "imei_md5"
      case "gaidmd5" | "gaid_md5" => "gaid_md5"
      case "oaidmd5" | "oaid_md5" => "oaid_md5"
      case "idfamd5" | "idfa_md5" => "idfa_md5"
      case "androididmd5" | "androidid_md5" => "androidid_md5"
      case _ => ""
    }
  }
}
