# == Schema Information
#
# Table name: acl_groups
#
#  id                  :integer          not null, primary key
#  group_name          :string(255)
#  organisation_id     :integer
#  router_inventory_id :integer
#  location_network_id :integer
#  created_at          :datetime
#  updated_at          :datetime
#  tagging_lists       :text
#

class StaticRoute < ActiveRecord::Base
  resourcify
  include AssociatedResource
  include RedisWrapper
  include PublicActivity::Model
  has_many :static_routing_lists
  # belongs_to :organisation
  # belongs_to :router_inventory
  belongs_to :location_network
  accepts_nested_attributes_for :static_routing_lists, :allow_destroy => true

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

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

  # def update_redis
  #   unless self.blank?
  #     set_redis
  #     lns = self.location_networks
  #     tags = self.tags.map(&:name)
  #     routers =  RouterInventory.where(location_network_id: lns.pluck(:id)) + RouterInventory.tagged_with(tags)  + self.router_inventories
  #     (routers.uniq || []).each{|x| x.update_redis}
  #   end
  # end

  def update_redis(des=false)
    set_redis(des)
    ris = self.router_inventories
    lns = self.location_networks
    tags = self.tags
    #remove previous config association
    cms = ConfigMapping.arel_table
    ConfigMapping.where( configurable_type: "StaticRoute", resourceable_type: 'RouterInventory', resourceable_id: ris.pluck(:id) ).where(cms[:configurable_id].not_eq(self.id)).each(&:destroy)
    ConfigMapping.where( configurable_type: "StaticRoute", resourceable_type: 'LocationNetwork', resourceable_id: lns.pluck(:id) ).where(cms[:configurable_id].not_eq(self.id)).each(&:destroy)
    ConfigMapping.where( configurable_type: "StaticRoute", resourceable_type: 'ActsAsTaggableOn::Tag', resourceable_id: tags.pluck(:id)).where(cms[:configurable_id].not_eq(self.id)).each(&:destroy)
    router =  RouterInventory.where(location_network_id: lns.pluck(:id)) + RouterInventory.tagged_with(tags)  + ris
    (router.uniq||[]).each do |y|
      y.update_redis unless y.blank?
    end
  end

  

  # def set_redis(des=false)
  #   return if  self.static_routing_lists.blank?
  #     route = []
  #     self.static_routing_lists.each do |x|
  #       route << {"NETWORK"=>x.network,"BITMASK"=>x.bitmask,"GATEWAY"=>x.gateway}.to_json
  #     end
  #     redis_set "route#{self.id}", route.to_json
  # end

  def set_redis(des=false)
    redis_set "route#{self.id}", get_redis_hash.to_json  unless des
    redis_del "route#{self.id}" if des
  end


  def get_redis_hash
    lists = self.static_routing_lists
    redis_list = []
    lists.each do |li|
      redis_list << {"NETWORK"=>li.network,"BITMASK"=>li.bitmask,"GATEWAY"=>li.gateway}
    end
    return redis_list
  end


  after_create do |x|
    x.update_redis
  end

  after_update do |x|
    x.update_redis
  end

  after_destroy do |x|
    redis_del "acl#{x.id}"
  end

  def self.aps_inventory_tags(org)
    aps = self.inventory(org)
    networks = org.location_networks.where('network_name IS NOT NULL') rescue []
    tag_list = []; network_list = []; ap_list = []
    (aps || []).each do |x|
      next if x.mac_id.blank?
      ap_list << {"id"=>x.id.to_s+"--inventory", "name"=>x.mac_id}
      x.tag_list.each {|y| tag_list << {"id"=>y+"--tag_list", "name"=>y} }
    end
    (networks || []).each do |y|
      next if y.network_name.blank?
      network_list << {"id"=>y.id.to_s+"--network_name", "name"=>y.network_name}
    end
    return tag_list.flatten.uniq+network_list+ap_list
  end

  def self.inventory(org)
    org.router_inventories.where('mac_id IS NOT NULL') rescue []
  end

  def self.get_inventories(org)
    aps = self.inventory(org)
    return self.aps_lists(aps,false)
  end

  def self.aps_lists(aps,allow_tags)
    ap_list =[]
    (aps || []).each do |x|
      next if x.mac_id.blank?
      if allow_tags
        (x.tag_list || []).each { |tag| ap_list << {"id"=>tag+"--tag", "name"=>tag} }
        ap_list << {"id"=>x.id.to_s+"--inventory", "name"=>x.mac_id} if x.tag_list.blank?
      else
        ap_list << {"id"=>x.id.to_s+"--inventory", "name"=>x.mac_id}
      end
    end
    ap_list.uniq
  end

  def self.get_all_aps(current_network)
    ap_list =[]
    aps = current_network.router_inventories.where('mac_id IS NOT NULL') rescue []
    (aps || []).each do |x|
      next if x.mac_id.blank?
      (x.tag_list || []).each { |tag| ap_list << {"id"=>tag+"--tag", "name"=>tag} }
      ap_list << {"id"=>x.id.to_s+"--inventory", "name"=>x.mac_id}
    end
    ap_list.uniq
  end
  def self.get_routers(current_network)
    aps = current_network.router_inventories.where('mac_id IS NOT NULL') rescue []
    return self.aps_lists(aps,true)
  end
end
