package mobvista.dmp.datasource.event_tag

import java.net.URI

import mobvista.dmp.common.CommonSparkJob
import org.apache.commons.cli.Options
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.commons.lang.StringUtils
import org.apache.spark.sql.types.{StringType, StructField, StructType}
import org.apache.spark.sql.{Row, SaveMode, SparkSession}

import scala.collection.mutable.ArrayBuffer


class DmpGaEventTag extends CommonSparkJob with Serializable {


  override protected def run(args: Array[String]): Int = {
    val commandLine = commParser.parse(options, args)
    if (!checkMustOption(commandLine)) {
      printUsage(options)
      return 1
    } else {
      printOptions(commandLine)
    }


    val today = commandLine.getOptionValue("today")
    val today_underline = commandLine.getOptionValue("today_underline")
    val coalesce = commandLine.getOptionValue("coalesce")
    val output = commandLine.getOptionValue("output")

    val spark = SparkSession
      .builder()
      .config("spark.rdd.compress", "true")
      .config("spark.io.compression.codec", "lz4")
      .config("spark.io.compression.lz4.blockSize", "64k")
      .config("spark.sql.orc.filterPushdown", "true")
      .config("spark.sql.autoBroadcastJoinThreshold", "209715200")
      .config("spark.sql.broadcastTimeout", "1200")
      .config("spark.sql.warehouse.dir", "s3://mob-emr-test/spark-warehouse")
      .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
      .enableHiveSupport()
      .getOrCreate()

    FileSystem.get(new URI(s"s3://mob-emr-test"), spark.sparkContext.hadoopConfiguration).delete(new Path(output), true)
    try {
     /* val sql =
        s"""
           |select  /*+ mapjoin(t2)*/ ios_idfa,
           |google_aid,
           |android_id,
           |lower(t1.platform) platform,
           |case when t2.package_name is not null then t2.package_name else 'unknown' end as package_name,
           |country_code country,
           |event_id event_name,
           |regexp_replace(revenue,'\\\\{|\\\\}','')  event_value,
           |arrival_ts event_time,
           |case when t2.package_name is not null then t2.second_tag  else 'other' end as second_tag,
           |install_ts install_time,
           |'$today'  update_date
           | from emr_doppler.event_$today_underline t1 left join (select a.game_id,a.store_id package_name,b.first_tag,b.second_tag from emr_doppler.player_new_store_game a join dwh.dim_package_tags_combine b on(a.store_id = b.package_name) group by a.game_id,a.store_id ,b.first_tag,b.second_tag ) t2
           | on(t1.game_id = t2.game_id)
           | where lower(t1.platform) in('android','ios') and event_id is not null and event_id != ''
           |and ((ios_idfa  rlike '$didPtn' and ios_idfa != '$allZero') or (google_aid rlike '$didPtn' and google_aid != '$allZero') or android_id  rlike '$andriodIdPtn' )
        """.stripMargin*/

      // emr_doppler.player_new_store_game -> player_store_game  由于之前的没有上传
      val sql =
        s"""
           |select  /*+ mapjoin(t2)*/ ios_idfa,
           |google_aid,
           |android_id,
           |lower(t1.platform) platform,
           |case when t2.package_name is not null then t2.package_name else 'unknown' end as package_name,
           |country_code country,
           |regexp_replace(revenue,'\\\\{|\\\\}','')  event_value,
           |case when t2.package_name is not null then t2.second_tag  else 'other' end as second_tag,
           |'$today'  update_date
           | from emr_doppler.event_$today_underline t1 left join (select a.game_id,a.store_id package_name,b.first_tag,b.second_tag from emr_doppler.player_store_game a join dwh.dim_package_tags_combine b on(a.store_id = b.package_name) group by a.game_id,a.store_id ,b.first_tag,b.second_tag ) t2
           | on(t1.game_id = t2.game_id)
           | where lower(t1.platform) in('android','ios')
           |and ((ios_idfa  rlike '$didPtn' and ios_idfa != '$allZero') or (google_aid rlike '$didPtn' and google_aid != '$allZero') or android_id  rlike '$andriodIdPtn' )
        """.stripMargin

      spark.sql(sql).createOrReplaceTempView("ods_dmp_event_tag_org")


      val sql1 =
        """
         select
            |X.device_id,
            |X.uuid,
            |X.platform,
            |X.device_type,
            |X.country,
            |X.package_name,
            |X.first_tag,
            |X.second_tag,
            |X.behavior_tag,
            |X.update_date
            |from (select
            |    '' uuid,
            |    case when platform="ios" then  ios_idfa else  google_aid end device_id,
            |    case when platform="ios" then  "idfa" else  "gaid" end device_type,
            |    platform,
            |    package_name,
            |    country,
            |    "Games" first_tag,
            |    second_tag,
            |    case when (event_value is null or event_value ='' ) then "game_active" else "game_purchase" end as behavior_tag,
            |    update_date
            |from ods_dmp_event_tag_org where android_id is null
            |union all
            |select
            |'' uuid,
            |    android_id device_id,
            |    "androidid"  device_type,
            |    platform,
            |    package_name,
            |    country,
            |    "Games" first_tag,
            |    second_tag,
            |    case when (event_value is null or event_value ='' ) then "game_active" else "game_purchase" end as behavior_tag,
            |    update_date
            |from ods_dmp_event_tag_org where android_id is not null ) X where X.device_id is not null
            |group by X.device_id,
            |X.uuid,
            |X.platform,
            |X.device_type,
            |X.country,
            |X.package_name,
            |X.first_tag,
            |X.second_tag,
            |X.behavior_tag,
            |X.update_date
        """.stripMargin

      spark.sql(sql1).coalesce(coalesce.toInt)
        .write
        .mode(SaveMode.Overwrite)
        .option("orc.compress", "zlib")
        .orc(output)


    } finally {
      if (spark != null) {
        spark.stop()
      }
    }
    0
  }


  def initConfig(conf: Configuration): Configuration = {
    import org.apache.hadoop.io.SequenceFile
    conf.set("mapreduce.output.compress", "true")
    conf.set("mapreduce.output.compression.codec", "org.apache.hadoop.io.compress.GzipCodec")
    conf.setBoolean("mapreduce.output.fileoutputformat.compress", true)
    conf.set("mapreduce.output.fileoutputformat.compress.type", SequenceFile.CompressionType.BLOCK.toString)
    conf
  }


  override protected def buildOptions(): Options = {
    val options = new Options
    options.addOption("today", true, "[must] today")
    options.addOption("today_underline", true, "[must] today_underline")
    options.addOption("coalesce", true, "[must] coalesce")
    options.addOption("output", true, "[must] output path")
    options
  }


}


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