class HeartbeatWorker
  include Sidekiq::Worker
  sidekiq_options :queue => :monitoring, :retry => false, :backtrace => true

  def perform(message)
    if message.is_a?(String) && message == "true"
      message = $redis.lpop('bravo')
      message = JSON.parse(message)
    end
    unless message.blank?
      p message
      #Add data to monitoring capped collection
      nasid = message["INFO"]["NASID"]
      ap_details = $redis.hgetall "AP:#{nasid}"
      message['ln_id'] = ap_details['ln_id']
      message['org_id'] = ap_details['org_id']
      MonitoringDataCapped.save_hb(message.deep_dup)

      mc = MonitoringChild.save_hb(message.deep_dup)

      last_hb = ap_details["last_hb"]
      config_update = false
      if mc.info["FIRST_HB"] == 1
        hb_freq = ap_details['hb_freq']
        interval = ap_details['hb_down_interval'].to_i
        if message['created_at'].blank?
          if last_hb.present? && (mc.created_at.to_i - last_hb.to_i) >= interval
            ApDowntime.create( mac: mc.info['NASID'], st: Time.zone.at(last_hb.to_i), et: mc.created_at, sec: (mc.created_at.to_i - last_hb.to_i))
          end
        elsif (message['ap_down_time'] || {})['sec'].to_i >= interval
          ApDowntime.create( mac: mc.info['NASID'], st: Time.zone.at(message['ap_down_time']['st'].to_i), et: Time.zone.at(message['ap_down_time']['et'].to_i), sec: message['ap_down_time']['sec'].to_i)
        end
        version=mc.info["PIAP_VERSION"]
        if (ap_details["version"].blank? && (version.present? && version.gsub('.','').to_i <= 20222)) || (ap_details["version"].present? && ap_details["version"].gsub('.','').to_i <= 20222 && version.present? && version.gsub('.','').to_i > 20222)
          config_update = true #RouterInventory.where(mac_id: mc.info['NASID']).last.try(:update_redis)
        end
        #Trigger init commands for Spoton devices
        InitCommandWorker.perform_async(mc.info['NASID'], ap_details)
      end
      #Set redis last HB time
      # ap_details = $redis.hgetall "AP:#{mc.info['NASID']}"

      current_active_uplink = ""
      current_active_uplink_type = ""
      
      if ap_details['hw_type'] == 'router'
        active_uplinks = JSON.parse(ap_details['uplinks'] || '{}')
        active_uplink_count = 0

        
        mc.uplink.each do |uplink|
          if uplink['IS'] == 1 && active_uplinks.key?(uplink['UID'])
            active_uplinks[uplink['UID']]['status'] = "active"
            current_active_uplink = uplink['UID']
            current_active_uplink_type = active_uplinks[uplink['UID']]['type']
            active_uplink_count += 1
          elsif active_uplinks.key?(uplink['UID'])
            active_uplinks[uplink['UID']]['status'] = "down"
          end
        end
      
        if active_uplink_count > 1
          mc.uplink.each do |uplink|
            if uplink['IS'] == 1 && active_uplinks[uplink['UID']]['is_primary']
              current_active_uplink = uplink['UID']
              current_active_uplink_type = active_uplinks[uplink['UID']]['type']
            end
          end
        end
      end
            
      curr_ap_details = []
      if message['created_at'].blank?
        curr_ap_details += ["prev_last_hb", last_hb] 
        curr_ap_details += ["last_hb", mc.created_at.to_i] 
      end

      firmware_changed = false
      bn_changed = false
      ip_changed = false

      if ap_details["version"].blank? || ap_details["version"] != mc.info["PIAP_VERSION"] || mc.info["FIRST_HB"] == 1
        curr_ap_details += ["version", mc.info["PIAP_VERSION"]]
        firmware_changed = true
      end

      if ap_details["BN"].blank? || ap_details["BN"] != mc.info["BN"] || mc.info["FIRST_HB"] == 1
        curr_ap_details += ["BN", mc.info["BN"]]
        bn_changed = true
      end

      curr_ap_details += ["p_version", ap_details["version"]] if ap_details["version"] != mc.info["PIAP_VERSION"] && mc.info["FIRST_HB"] == 1

      if ap_details["pub_ip"].blank? || (mc.s_info.present? && ap_details["pub_ip"] != mc.s_info["PUBLIC_IP"]) || (mc.info||{})["FIRST_HB"] == 1
        curr_ap_details += ["pub_ip", mc.s_info["PUBLIC_IP"]]
        ip_changed = true
      end

      if ap_details['hw_type'] == 'router'
        curr_ap_details += ["active_uplinks", active_uplinks.to_json]
        curr_ap_details += ["curr_active_uplink", current_active_uplink]
        curr_ap_details += ["curr_active_uplink_type", current_active_uplink_type]
      end
      # $redis.hset "AP:#{mc.info['NASID']}", "prev_last_hb", last_hb
      # $redis.hset "AP:#{mc.info['NASID']}", "last_hb", mc.created_at.to_i
      # $redis.hset "AP:#{mc.info['NASID']}", "version", mc.info["PIAP_VERSION"] if ap_details["version"].blank? || ap_details["version"] != mc.info["PIAP_VERSION"] || mc.info["FIRST_HB"] == 1
      # $redis.hset "AP:#{mc.info['NASID']}", "p_version", ap_details["version"] if ap_details["version"] != mc.info["PIAP_VERSION"] && mc.info["FIRST_HB"] == 1
      # $redis.hset "AP:#{mc.info['NASID']}", "pub_ip", mc.s_info["PUBLIC_IP"] if ap_details["pub_ip"].blank? || (mc.s_info.present? && ap_details["pub_ip"] != mc.s_info["PUBLIC_IP"])  || mc.info["FIRST_HB"] == 1
      if mc.radio != nil
        mc.radio.each do |radio|
          if radio['BAND'].to_s == '1'
            curr_ap_details += ["C_24GHZ" , radio['CHANNEL']]
            curr_ap_details += ["P_24GHZ" , radio['TXPOWER']]
            # $redis.hset "AP:#{mc.info['NASID']}", "C_24GHZ" , radio['CHANNEL']
            # $redis.hset "AP:#{mc.info['NASID']}", "P_24GHZ" , radio['TXPOWER']
          else
            curr_ap_details += ["C_5GHZ" , radio['CHANNEL']]
            curr_ap_details += ["P_5GHZ" , radio['TXPOWER']]
            # $redis.hset "AP:#{mc.info['NASID']}", "C_5GHZ" , radio['CHANNEL']
            # $redis.hset "AP:#{mc.info['NASID']}", "P_5GHZ" , radio['TXPOWER']
          end
        end
      end
      $redis.hmset "AP:#{mc.info['NASID']}", curr_ap_details

      if firmware_changed || bn_changed || ip_changed
        worker_params = prepare_router_inventory_worker_params(mc, ap_details, firmware_changed, bn_changed, ip_changed, current_active_uplink)
        Rails.logger.info("[HEARTBEAT] Queuing RouterInventoryUpdateWorker with params: #{worker_params.inspect}")
        RouterInventoryUpdateWorker.perform_async(worker_params)
      end

      if ap_details['vendor_type'] == '6' #&& ap_details['test_device'] != 'true'
        if (mc.info['CONSUME_ID'] != ap_details['CONSUME_ID']) && ap_details['test_device'] != 'true'
          ri=RouterInventory.where(mac_id: mc.info['NASID']).last
          p "[OPENWIFI][SWITCH][APPLY] Applying latest config for #{mc.info['NASID']}--- #{mc.id}"
          ri.update_redis(true,true,true) if ri.present?
        end

        if ap_details["pending_upgrade"].present? && ap_details["pending_upgrade"].to_i > 0
          pending_upgrade_id = ap_details["pending_upgrade"].to_i
          job_id = ap_details["upgrade_job_id"]
          unless ap_details['ongoing_upgrade'] == "true" && job_id.present?
            PushUpgradeWorker.perform_async(mc.info['NASID'], pending_upgrade_id)
          end
        end
      else
        RouterInventory.where(mac_id: mc.info['NASID']).last.try(:update_redis) if (mc.info["FIRST_HB"] == 1 && config_update)
      end
      
      if (mc.info["FIRST_HB"] == 1 || ap_details['hw_part_no'].blank?) && mc.info["HW_PART_NO"].present? && mc.info["HW_PART_NO"] != ""# && !mc.info["HW_PART_NO"].nil?
        ri = RouterInventory.find_by_mac_id mc.info['NASID']
        ri.set_hw_part_no mc.info["HW_PART_NO"] if ri.present? && ri.hardware_part_id.blank?
      end
      if ap_details['alert'] == "1" && JSON.parse($redis.get('PCC:ORG:ALERT:STATUS') || '[]').include?(ap_details['org_id']) #&& ["4551", "25", "273", "14", "433", "477"].include?(ap_details['org_id'])
        #Create Alerts worker
        jid=AlertsWorker.perform_async(message, mc.created_at.to_i)

        puts "Heartbeat worker completed --- Alerts Worker #{jid}"
      end

    end
  end

  def prepare_router_inventory_worker_params(mc, ap_details, firmware_changed, bn_changed, ip_changed, current_active_uplink)
    worker_params = {
      nasid: mc.info['NASID']
    }
    
    if firmware_changed
      worker_params[:current_firmware] = mc.info["PIAP_VERSION"] 
      worker_params[:previous_firmware] = ap_details["version"] if ap_details["version"].present?  
    end
    
    if bn_changed
      worker_params[:build_number] = mc.info["BN"]
    end
    
    if ip_changed
      if mc.s_info.present? && mc.s_info["PUBLIC_IP"].present?
        worker_params[:public_ip] = mc.s_info["PUBLIC_IP"]
      end

      if current_active_uplink.present?
        worker_params[:current_active_uplink] = current_active_uplink.to_i
      end

      Rails.logger.info("[HEARTBEAT] IP changed - adding IP data: public_ip=#{worker_params[:public_ip]}, current_active_uplink=#{worker_params[:current_active_uplink]}")

    end
    
    worker_params
  end
  
end
