package gg.analytics



import com.google.api.services.analytics.model.GaData
import gg.util.*
import gg.util.DateTimespan.getDateTimespan
import io.vertx.core.AbstractVerticle
import io.vertx.core.Future
import org.joda.time.DateTime
import org.slf4j.LoggerFactory
import org.slf4j.MDC
import redis.client.RedisClient
import redis.client.cmdDel
import redis.client.cmdHGet
import redis.client.cmdHSet
import redis.protocol.reply.NullBulkString

@Suppress("unused")
class DataVerticle : AbstractVerticle() {

    private val logger = LoggerFactory.getLogger(this::class.java)
    private var redisConfPort = 6479
    private var redisConfHost = "localhost"
    private var busConf = "redis_bus"
    private var page = 0
    private val pageSize = 10000
    private var datetime_import = DateTime();


    override fun start(startFuture: Future<Void>?) {
        MDC.put("verticle", "data")
        val conf = Config.get()
        redisConfPort = conf.getJsonObject("redis").getInteger("port")
        redisConfHost = conf.getJsonObject("redis").getString("host")
        busConf = conf.getJsonObject("event_bus").getString("bus_name")
        logger.debug("initialising api version {}", conf.getString("version"))
        logger.debug("Fetching data from GA...")
        startFuture?.complete()
        vertx.eventBus().consumer<Int>(busConf) { message ->
            run {
                page=message.body()
                doAnalyticsQueryandStore()
                message.reply(true);
            }
        }
//        doAnalyticsQueryandStore()

    }

    private fun doAnalyticsQueryandStore() {
        logger.debug( "Doing analytics for page " + page)
        /* Adding arguments for google analytics */
        val params = mutableMapOf<String, Int>()
        params.put("pageSize",pageSize)
        params.put("page",page)
        params.put("dateTimespan", getDateTimespan())

        val result = QueryAnalytics.main(params)

        var initialResult = if (page == 0) 0 else (1 + pageSize * page)
        val maxResults = result.totalResults
        logger.debug("Got results, putting it in redis")
        storeInRedis(result)
        if(initialResult == 0) {
            logger.debug("IS FIRST PAGE, adding new events")
            initialResult = (1 + pageSize * ++page)
            while(initialResult < maxResults) {
                logger.debug("   Adding page " + page + " to event bus")
                /* Invoke using the event bus. */
                EventBusHandler.sendIntEvent(busConf, page, this)
                initialResult = (1 + pageSize * ++page)
            }
        }
    }

    private fun storeInRedis(result: GaData) {
        val rs = RedisClient(redisConfHost, redisConfPort)
        rs.connect()
        for (item in result.rows){
         // Now create matcher object.
          val key = AdViewRegex.getAdId(item[0]);
            val datetime_import_reply = rs.execute { cmdHGet(key, "datetime_import")}
            if(datetime_import_reply !is NullBulkString) {
                val obj_datetime = DateTime(datetime_import_reply.toString())
                if(!DateTimeImport.equals(obj_datetime))
                {
                    rs.execute { cmdDel(key) }
                }
            }
            rs.execute { cmdHSet(key, item[0], item[1]) }
            rs.execute { cmdHSet(key, "timespan", Integer.toString(DateTimespan.getDateTimespan())) }
            rs.execute { cmdHSet(key, "datetime_import", datetime_import.toString()) }
            val total_views_reply = rs.execute { cmdHGet(key, "total_views")}
            var total_views = Integer.parseInt(item[1])
            if(total_views_reply !is NullBulkString) {
                total_views = (Integer.parseInt(total_views_reply.toString()) + Integer.parseInt(item[1]))
            }
            rs.execute { cmdHSet(key, "total_views", total_views.toString()) }
        }
        rs.close()
    }


    override fun stop(stopFuture: Future<Void>?) {
    }
}