# == Schema Information
#
# Table name: radio_profiles
#
#  id              :integer          not null, primary key
#  name            :string(255)
#  country_code    :string(255)
#  organisation_id :integer
#  created_at      :datetime
#  updated_at      :datetime
#

class RadioProfile < ActiveRecord::Base
  serialize :vendor_details, Hash
  
  include AssociatedResource #ConfigMapping Association and its methods (app/models/concerns/associated_resource.rb)
  include RedisWrapper
  extend RedisWrapper
  include PublicActivity::Model

  tracked owner: ->(controller, model) { controller && controller.tracked_current_user },params:
  { :attributes => proc {|controller, model_instance| {"radio_profile(#{model_instance.name})" => model_instance.changes}}},organisation_id: ->(controller, model) { controller && controller.tracked_current_user.organisation_id },location_network_id: nil

  tracked assumed_by: proc {|controller, model| controller.user_assumed_by if controller}

  belongs_to :location_network
  belongs_to :organisation
  has_many :radio_settings, dependent: :destroy
  has_one :radio_management, dependent: :destroy

  accepts_nested_attributes_for :radio_settings, allow_destroy: true
  accepts_nested_attributes_for :radio_management, allow_destroy: true

  attr_accessor :skip_sync

  def skip_sync
    @skip_sync = false
  end

  after_save :update_redis

  after_create do |x|
    if x.location_network.vendor_type == "3"
      res = Meraki::Wireless::ConfigurationService.new(x.location_network).create_radio_profile x
    end
    if x.location_network.vendor_type == "5"
      if !x.skip_sync
        radiodevices = x.associated_resources
        networkselcted = []
        networkselcted = radiodevices.select{|x| x.split(':')[0] == "network"} 
        unless networkselcted.blank?
          Ruckus::ConfigurationService.new(x.location_network).update_radio_parameters x, x.location_network
        else
          radiodevices.each do |ap|  
            accpoint = RouterInventory.where(:id=>ap.split(':')[1]).last
            Ruckus::ConfigurationService.new(x.location_network).update_radio_parameters x, accpoint unless accpoint.blank?
          end
        end
      end
    end
    x.update_redis
  end

  after_update do |x|
    if x.location_network.vendor_type == "3"
      res = Meraki::Wireless::ConfigurationService.new(x.location_network).update_radio_profile x
    end
    x.update_redis
  end

  after_destroy do |x|
    if x.location_network.vendor_type == "3"
      res = Meraki::Wireless::ConfigurationService.new(x.location_network).delete_radio_profile x
    end
    x.update_redis
  end

  def json_build
    radio_setngs = []
    radio_settings.each do |n|
      radio_setngs << n.json_build
    end
    r_m = radio_management.json_build
    {:id => self.id, :name => self.name, :country_code => self.country_code, :country_code => self.country_code, :radio_settings => radio_setngs, :radio_management => r_m}
  end

  def update_redis
    set_redis
    ris = self.router_inventories
    lns = self.location_networks
    routers = RouterInventory.where(location_network_id: lns.pluck(:id)) + ris
    #remove previous config association
    cms = ConfigMapping.arel_table
    ConfigMapping.where( configurable_type: "RadioProfile", resourceable_type: 'RouterInventory', resourceable_id: ris.pluck(:id) ).where(cms[:configurable_id].not_eq(self.id)).each(&:destroy)
    ConfigMapping.where( configurable_type: "RadioProfile", resourceable_type: 'LocationNetwork', resourceable_id: lns.pluck(:id) ).where(cms[:configurable_id].not_eq(self.id)).each(&:destroy)
    #TODO: Update redis only for resources which does not have previous config mapping
    (routers.uniq || []).each { |y| y.update_redis }
  end

  def set_redis
    redis_set "radio#{self.id}", {"RADIO_PROFILE_ID"=> "#{self.id}","NAME"=> self.name, "COUNTRY_CODE" => self.country_code, "RADIO_SETTINGS" => self.radio_settings.map {|rs| {"BAND" => rs.band == "5" ? "2" : "1","CH_UTIL_EN" => rs.channel_utlilization ? 1 : 0,  "DISABLE" => rs.is_disable? ? 1 : 0, "COUNTRY_IE" => rs.country_ie? ? 1 : 0, "CHANNEL" => "#{rs.channel}", "TXPOWER" => "#{rs.power}", "REQUIRE_MODE" => "#{rs.require_mode}", "CH_BW" => "#{rs.bandwidth}"}}}.to_json
  end

  def self.set_default_radio
    redis_set "default_radio", self.default_radio.to_json
  end

  def self.default_radio
    {"RADIO_PROFILE_ID"=> "0","NAME"=> "Radio Default", "COUNTRY_CODE" => "US", "RADIO_SETTINGS" => [{"BAND" => "1","CH_UTIL_EN" => 0, "DISABLE" => 0, "COUNTRY_IE" => 1, "CHANNEL" => "0", "TXPOWER" => "0", "REQUIRE_MODE" => "g"},{"BAND" => "2", "DISABLE" => 0, "COUNTRY_IE" => 1, "CHANNEL" => "0", "TXPOWER" => "0", "REQUIRE_MODE" => "g", "CH_BW" => "80"}]}
  end

  def self.grouped_collection_of_ap_and_network network, radio_profile=nil
    hash = {}
    ris = network.router_inventories
    ris_config = ConfigMapping.where( configurable_type: "RadioProfile", resourceable_type: 'RouterInventory', resourceable_id: ris.map(&:id) ).pluck(:resourceable_id)
    ris_config -= radio_profile.router_inventories.pluck(:id) unless radio_profile.blank?
    hash["Router Inventory"] = (ris.uniq - RouterInventory.find_all_by_id(ris_config)).map {|ri| ["#{ri.name.present? ? (ri.name + " (#{ri.mac_id.last(8)})") : ri.mac_id}", "AP:#{ri.id}"]}
    network_radio_profile = nil
    network_radio_profile = radio_profile.location_networks unless radio_profile.blank?
    hash["Router Inventory"] += [["All", "network:#{network.id}"]] if network_radio_profile.present? || network.associated_radio_profile.blank?
    hash
  end
end
