# == Schema Information
#
# Table name: network_ssids
#
#  id                    :integer          not null, primary key
#  ssid_name             :string(255)
#  ssid_mode             :string(255)
#  nat                   :string(255)
#  is_enabled            :boolean
#  is_hidden             :boolean
#  is_isolate            :boolean
#  security_mode         :string(255)
#  wpa_algorithm         :string(255)
#  key_renewal_interval  :string(255)
#  wpa_key               :string(255)
#  psk_type              :string(255)
#  location_network_id   :integer
#  created_at            :datetime
#  updated_at            :datetime
#  acl_mac               :string(255)
#  mac_filter_policy     :string(255)
#  acl_mac_list          :text
#  vlan_id               :integer
#  captive_portal        :string(255)
#  splash_url            :text
#  wallgarden            :string(255)
#  walled_garden_range   :text
#  overwrite_success_url :string(255)
#  success_url           :text
#  dhcp_range_start      :string(255)
#  dhcp_range_end        :string(255)
#  dhcp_relay_server     :string(255)
#  dhcp_lease_time       :string(255)
#  auth_radius_id        :string(255)
#  acc_radius_id         :string(255)
#  acc_radius_enabled    :string(255)
#  ip_address            :string(255)
#  subnet_mask           :string(255)
#  ssid_qos              :string(255)
#  enable_ssid_qos       :boolean
#  per_user_qos          :string(255)
#  radio_band            :string(255)      default("2.4")
#  max_association       :integer          default(0)
#  wds_enabled           :boolean          default(FALSE)
#  dns_mode              :string(255)      default("1")
#  dns_primary           :string(255)
#  dns_secondary         :string(255)
#  wna                   :string(255)      default("1")
#  dhcp_mappings         :text(2147483647)
#  default_interim_time  :string(255)      default("300")
#  default_idle_timeout  :string(255)      default("1800")
#

class NetworkSsid < ActiveRecord::Base
  resourcify
  include RedisWrapper
  include PublicActivity::Model
  include IpValidator
  validates :ssid_name, length: {maximum: 32}
  validate :dhcp_ranges_validation, :if => :check_dhcp_validations?
  validate :dhcp_mappings_validation, :if => :check_dhcp_validations?
  validate :ip_address_validation, :if => :check_dhcp_validations?
  validate :subnet_mask_validation, :if => :check_dhcp_validations?

  serialize :dhcp_mappings, Array
  serialize :dhcp_ranges, Array
  serialize :dhcp_options, Array
  serialize :multi_psk_options, Array
  serialize :radio_bands, Array #TODO: Need to migrate data form radio_band to radio_bands
  serialize :vendor_details, Hash

  tracked owner: ->(controller, model) { controller && controller.tracked_current_user },params: { :attributes => proc {|controller, model_instance| { "network_ssid(#{model_instance.ssid_name})" => model_instance.changes}}},organisation_id: ->(controller, model) { (controller && controller.tracked_current_user) ? controller.tracked_current_user.organisation_id : model.location_network.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}

  DNS_MODE = [["Use ISP(default)", "1"],["Custom", "2"],["Custom with content filtering", "3"]]  
  belongs_to :location_network
  #belongs_to :v_lan, foreign_key: "vlan_id"
  belongs_to :radius_authentication, foreign_key: "auth_radius_id", class_name: "RadiusConfiguration"
  belongs_to :radius_accounting, foreign_key: "acc_radius_id", class_name: "RadiusConfiguration"
  has_many :config_mappings, as: :configurable, dependent: :destroy
  has_many :router_inventories, through: :config_mappings, source: :resourceable, source_type: "RouterInventory"
  has_many :associated_networks, through: :config_mappings, source: :resourceable, source_type: "LocationNetwork"
  has_many :associated_hardware_categories, through: :config_mappings, source: :resourceable, source_type: "HardwareCategory"
  has_many :tags, through: :config_mappings, source: :resourceable, source_type: "ActsAsTaggableOn::Tag", class_name: 'ActsAsTaggableOn::Tag'
  has_many :router_inventories, through: :config_mappings, source: :resourceable, source_type: "RouterInventory"
  has_one :v_lan, dependent: :destroy
  has_one :roaming, dependent: :destroy
  has_one :hotspot20, dependent: :destroy
  has_and_belongs_to_many :wlan_groups, -> { uniq }
  
  attr_accessor :associated_aps_and_tags, :skip_sync

  scope :on_router_mode, -> { where(ssid_mode: "1") }
  accepts_nested_attributes_for :v_lan, allow_destroy: true
  accepts_nested_attributes_for :roaming, allow_destroy: true
  accepts_nested_attributes_for :hotspot20, allow_destroy: true


  def skip_sync
    @skip_sync || false
  end
  
  def check_dhcp_validations?
    self.ssid_mode == "1" && self.dhcp_relay_server == "2"
  end

  def dhcp_ranges_validation
    ip = self.ip_address
    self.dhcp_ranges.each_with_index do |ranges, index|
      start_range = ranges["START"].split('.')[3].to_i
      end_range = ranges["END"].split('.')[3].to_i
      errors.add(:dhcp_ranges, "Start range cannot be blank") if !required_fields(ranges["START"])
      errors.add(:dhcp_ranges, "End range cannot be blank") if !required_fields(ranges["END"])
      if required_fields(ranges["START"]) == true
        errors.add(:dhcp_ranges, "of Start IP address is invalid- #{ranges['START']}") if !validate_ip(ranges["START"])
        errors.add(:dhcp_ranges, "of Start IP Address is not in the range of IP and Gateway fields! - #{ranges['START']}") if !ip_range(ranges["START"])
        if(start_range == end_range || ip == start_range)
          errors.add(:dhcp_ranges, "Start field cannot contain same IP Address! - #{ranges['START']}")
        end
        errors.add(:dhcp_ranges, "IP should not be in range DHCP End and DHCP Start range! - #{ranges['START']}") if !dhcp_range_check(ranges["START"], index)
      end 
      
      if required_fields(ranges["END"]) == true
        errors.add(:dhcp_ranges, "of End IP address is invalid- #{ranges['END']}") if !validate_ip(ranges["END"])
        errors.add(:dhcp_ranges, "of End IP Address is not in the range of IP and Gateway fields! - #{ranges['END']}") if !ip_range(ranges["END"])
        if !(end_range > start_range)
          errors.add(:dhcp_ranges, "DHCP End range should be greater than DHCP Start range! - #{ranges['END']}")
        end
        if(end_range == start_range || ip == end_range)
          errors.add(:dhcp_ranges, "End field cannot contain same IP Address! - #{ranges['END']}")
        end
        errors.add(:dhcp_ranges, "IP should not be in range DHCP End and DHCP Start range! - #{ranges['END']}") if !dhcp_range_check(ranges["END"], index)
      end
    end
  end

  def dhcp_mappings_validation
    all_ip = []
    all_mac = []
    ip = self.ip_address
    self.dhcp_mappings.each do |mappings|
      all_ip << mappings["IPADDR"]
      all_mac << mappings["MAC"].upcase
      ip_mapping = mappings["IPADDR"]
      errors.add(:dhcp_mappings, "IP address cannot be blank") if !required_fields(mappings["IPADDR"])
      errors.add(:dhcp_mappings, "MAC address cannot be blank") if !required_fields(mappings["MAC"])
      if required_fields(mappings["IPADDR"]) == true
        errors.add(:dhcp_mappings, "of IP address is invalid - #{mappings['IPADDR']}") if !validate_ip(mappings["IPADDR"])
        errors.add(:dhcp_mappings, "IP Address is not in the range of IP and Gateway fields! - #{mappings['IPADDR']}") if !ip_range(mappings["IPADDR"])
        errors.add(:dhcp_mappings, "Field cannot contain same IP Address! - #{mappings['IPADDR']}") if !dhcp_range_check(mappings["IPADDR"], -1)
        if (ip == ip_mapping)
          errors.add(:dhcp_mappings, "Field cannot contain same IP Address! - #{mappings['IPADDR']}")
        end
      end

      if required_fields(mappings["MAC"]) == true
        errors.add(:dhcp_mappings, "Invalid MAC address - #{mappings['MAC']}") if !validate_mac_id(mappings["MAC"])
      end
    end
    
    if all_ip.count != all_ip.uniq.count
      errors.add(:dhcp_mappings, "few IP address are duplicate")
    end
    if all_mac.count != all_mac.uniq.count
      errors.add(:dhcp_mappings, "Same macid mapped more than once")
    end
  end

  def ip_address_validation
    errors.add(:ip_address, "cannot be blank") if !required_fields(self.ip_address)
    if required_fields(self.ip_address) == true
      errors.add(:ip_address, "Invalid - #{ip_address}") if !validate_ip(self.ip_address)
      errors.add(:ip_address, "IP should not be in range DHCP End and DHCP Start range! - #{ip_address}") if !dhcp_range_check(self.ip_address, nil)
    end
  end

  def subnet_mask_validation
    errors.add(:subnet_mask, "cannot be blank") if !required_fields(self.subnet_mask)
    if required_fields(self.subnet_mask) == true
      errors.add(:subnet_mask, "Invalid - #{subnet_mask}") if !validate_ip(self.subnet_mask)
    end
  end

  def get_radio_band
    if self.radio_bands.size == 1
      rb = '2' if self.radio_bands.first == '5'
      rb = '1' if self.radio_bands.first == '2.4'
    else
      rb = '3' if self.radio_bands.include?('5') && self.radio_bands.include?('2.4')
    end

    rb
  end

  def update_redis
    captive_portal = {}
    radius = {}
    location_network = self.location_network
    self.multi_vendor_enablement unless self.vendor_details.blank? if ["3"].include?(location_network.vendor_type)
    OpenWifi::ProvisioningService.new(self.location_network).set_radius_proxy_config if location_network.vendor_type == '4' && self.radius_gw_proxy && ((self.security_mode == 'psk2' && self.multi_psk == 'radius') || self.captive_portal.to_i != 0)
    if self.captive_portal.eql?"2"
      wavespot_portal =  APPLICATION['defaults']['CAPTIVE_PORTAL']
      wavespot_security =  APPLICATION['defaults']['SECURITY']
      captive_portal =  {"PORTAL_ENABLE" => wavespot_portal["PORTAL_ENABLE"],
          "PORTAL_REDIR_URL" => wavespot_portal["PORTAL_REDIR_URL"],
          "MAC_AUTH" => self.mac_auth,
          "WL_ENABLE" => wavespot_portal["WL_ENABLE"],
          "WL_CONFIG" => wavespot_portal["WL_CONFIG"],
          "ORIG_URL" => wavespot_portal["ORIG_URL"],
          "QOS" => {"BW_ENABLE" => wavespot_portal["QOS"]["BW_ENABLE"], "BW"=> wavespot_portal["QOS"]["BW"]}}
      radius = {"AUTH_TYPE" => (self.security_mode.blank? ? 'none' : self.security_mode),"PASS_PHRASE" =>  ((self.psk_type.blank? || self.psk_type == "custom")  ? self.wpa_key : ""),
          "AUTH_SERVER" => wavespot_security["AUTH_SERVER"],"AUTH_PORT" => wavespot_security["AUTH_PORT"],
          "AUTH_SECRET" => wavespot_security["AUTH_SECRET"], "ACCT_SERVER" => wavespot_security["ACCT_SERVER"],
          "ACCT_PORT" => wavespot_security["ACCT_PORT"],"ACCT_SECRET" => wavespot_security["ACCT_SECRET"]}
    else
       captive_portal =  { "PORTAL_ENABLE" => self.wds_enabled? ? 0 : self.captive_portal != '0' ? 1 : 0,
          "PORTAL_REDIR_URL" => self.splash_url,
          "WL_ENABLE" => (self.wallgarden).to_i,
          "WL_CONFIG" => (self.walled_garden_range.blank? ? [] : self.walled_garden_range.split(",")),
          "ORIG_URL" => self.overwrite_success_url == "false" ? "1" : "0",
          "SUCC_URL" => self.success_url,
          "QOS" => {"BW_ENABLE" => self.per_user_qos.to_i == 0 ? 0 : 1, "BW"=> "#{self.per_user_qos.to_i}"},
          "DEF_INT_UPDATE_INTV" => self.default_interim_time,
          "DEF_IDLE_TO" => self.default_idle_timeout,
          "PORTAL_AUTH_MODE" => "1" #Default should be '1' for CP with radius
          }
          captive_portal['MAC_AUTH'] = self.mac_auth if self.captive_portal == "1"
          #NOTE: PORTAL_AUTH_MODE - '1'=Radius, '2'=Local Auth
          captive_portal['PORTAL_AUTH_MODE'] = '2' if self.captive_portal == "3" #CP with local auth
          radius_auth_server = RadiusConfiguration.find_by_id(self.auth_radius_id)
          radius = {"AUTH_TYPE"=> (self.security_mode.blank? ? 'none' : self.security_mode),"PASS_PHRASE"=> ((self.psk_type.blank? || self.psk_type == "custom")  ? self.wpa_key : "")}
          unless radius_auth_server.blank?
            radius["AUTH_SERVER"] = radius_auth_server.radius_ip
            radius["AUTH_PORT"] = radius_auth_server.radius_port
            radius["AUTH_SECRET"] = radius_auth_server.radius_secret
          end
          radius_auth_server = RadiusConfiguration.find_by_id(self.acc_radius_id)
          unless radius_auth_server.blank?
            radius["ACCT_SERVER"] = radius_auth_server.radius_ip
            radius["ACCT_PORT"] = radius_auth_server.radius_port
            radius["ACCT_SECRET"] = radius_auth_server.radius_secret
          end
    end
    vlanid = self.v_lan
    vlanid = vlanid.v_lan_id unless vlanid.blank?
    vlanid = nil if vlanid == '0' || self.ssid_mode == '1'
    rb = nil
    rb = self.get_radio_band

    redis_set "ns#{self.id}", { "SSID_UNIQ_ID" => self.id.to_s, "MODE_ROUTER" => self.ssid_mode.to_i, "NAT" => self.nat.to_i, "WNA" => self.wna.to_i,
                                "SSID" => self.ssid_name, "DISABLE" => (self.is_enabled ? 0 : 1), "HIDDEN" => (self.is_hidden ? 1 : 0) ,
                                "ISOLATE" => (self.is_isolate ? 1 : 0), "PROTO" => "static","VLANID" => vlanid, "IPADDR" => (self.ssid_mode == '1' ? self.ip_address : nil),
                                "NETMASK" => (self.ssid_mode == '1' ? self.subnet_mask : nil),
                                "ACL_MAC" => { "MAC_FILTER_ENABLE" => (self.acl_mac).to_i, "MAC_FILTER_POLICY" => self.mac_filter_policy.to_i,
                                               "ACL_MAC_LIST" => (self.acl_mac_list.blank? ? [] : self.acl_mac_list.split(",")) },
                                "QOS" => {"BW_ENABLE" => self.enable_ssid_qos? ? 1 : 0, "BW"=> "#{self.ssid_qos.to_i}"},
                                "SECURITY" => radius,
                                "DHCP" => { "LEASE_TIME" => self.dhcp_lease_time,"DHCP_ENABLE"=> self.dhcp_relay_server ,"RANGE_START" => (["1","3"].include?self.dhcp_relay_server) ? "" : self.dhcp_ranges.blank? ? "" : self.dhcp_ranges.first['START'],"RANGE_END" => self.dhcp_ranges.blank? ? "" : self.dhcp_ranges.first['END'] ,"MAPPINGS" => self.dhcp_mappings,"RANGES" => self.dhcp_ranges, "OP" => self.dhcp_options},
                                "CAPTIVE_PORTAL" => captive_portal,
                                "WDS" => self.wds_enabled? ? 1 : 0,
                                "BAND" => rb,
                                "DEVICE_5GHZ" => (self.radio_bands.size == 1 && self.radio_bands.include?('5')) ? 1 : 0,
                                "MAX_ASSOC" => "#{self.max_association}",
                                "DNS" => {"MODE" => self.dns_mode, "PRI_DNS" => self.dns_primary.to_s, "SEC_DNS" => self.dns_secondary.to_s},
                                "UPLINK_PRIO" => self.uplink_priority
                              }.to_json
    #update all router inventory on redis

    router = self.router_inventories + RouterInventory.tagged_with(self.tags) + (self.associated_networks.first.try(:router_inventories) || [] ) + self.location_network.router_inventories.includes(:hardware_part).where("hardware_parts.hardware_category_id" => associated_hardware_categories.map(&:id))
    (router.uniq||[]).each do |y|
      y.update_redis unless y.blank?
    end
  end

  after_update do |ssid|
    if ssid.location_network.vendor_type == "5"
      if !ssid.skip_sync
        Ruckus::ConfigurationService.new(ssid.location_network).update_wlan(ssid) if ssid.changes.keys.count > 0 && ssid.changes.keys.first != "vendor_details"
        ssid.set_wlan_and_ap_group if ssid.changes['associated_aps_and_tags'].present?
      end
    else
      ssid.update_redis
    end
  end


  after_create do |x|
    if x.location_network.vendor_type == "5"
      #NOTE: By default the SSID would be assigned to 'default' WLAN group on Ruckus if it is associated only to network(rkzone). 
      # => If it is associated to any other combination then we need to create a WLAN group and assigned to respective SSID.
      if !x.skip_sync
        Ruckus::ConfigurationService.new(x.location_network).create_wlan x
        x.set_wlan_and_ap_group if !x.associated_aps_and_tags.include?("network:#{x.id}") 
      end
    else
      x.update_redis
    end
  end

  def set_wlan_and_ap_group
    #TODO: Each combination of assocaited resources will have separate wlan group on ruckus
    # wlanGroupIds
    # => Check whether WLAN group for this SSIDs combination exists in DB
    # => If exists then return the WLAN group ID from DB
    # => IF not then create a WLAN group with these SSIDs combination

    # assoc_resources = self.associated_aps_and_tags
    # aps_tags_ssids =  assoc_resources.select {|q| !q.match(/network/)}
    assoc_ris = self.router_inventories

    #find the SSIDs combination's WLAN_group.
    # => present then assign respective wlan group to ssid
    # => Not present then create a wlan group and assign to ssid
    existing_wlan_group_ssids = {}
    self.location_network.wlan_groups.includes(:network_ssids).select("network_ssids.id").references(:network_ssids).map {|d| existing_wlan_group_ssids[d.network_ssids.map(&:id).sort] = d }
    ap_groups = Set.new
    assoc_ris.each do |ri|
      ri_assoc_ssids = ri.get_all_associated_ssids
      ri_assoc_ssid_ids = ri_assoc_ssids.map(&:id).sort
      if existing_wlan_group_ssids.keys.include?(ri_assoc_ssid_ids)
        wlan_group = existing_wlan_group_ssids[ri_assoc_ssid_ids]
        ri.ap_group_id = wlan_group.ap_group.id
        ap_groups << wlan_group.ap_group
      else
        #create new wlan group and assign ssid
        wl_g = self.location_network.wlan_groups.create name: "WG(LN-#{self.location_network_id}-#{SecureRandom.hex(3)})", network_ssid_ids: ri_assoc_ssid_ids
        ri.ap_group_id = wl_g.ap_group.id
        #Add ssid to respective wlan group
        ri_assoc_ssids.each do |ssid|
          Ruckus::ConfigurationService.new(self.location_network).add_member_to_wlan_group(wl_g, ssid)
        end
        #Reove the SSID from default group
        default_wl_g = self.location_network.get_default_wlan_group
        Ruckus::ConfigurationService.new(self.location_network).remove_member_from_wlan_group(default_wl_g, self) if default_wl_g.present?
        ri.ap_group_id = wl_g.ap_group.id
        ap_groups << wl_g.ap_group
      end

      ri.save
    end
    ap_groups.each do |ap_group|
      Ruckus::ConfigurationService.new(self.location_network).add_members_to_ap_group(ap_group)
    end
    # if assoc_ris.present?
    #   nw_ssids = self.location_network.associated_network_ssids
    #   aps_tags_ssids.each do |aps_ssid|

    #   end
    # end
    
    # s=self.location_network.network_ssids.map {|d| [d.id,d.associated_aps_and_tags]}
    # s.push([self.id, self.associated_aps_and_tags])
    # wlg={}
    # s.uniq.each {|q| q.last.each {|w| wlg[w] ||= []; wlg[w] << q.first}}
    # aps_tags_ssids =  wlg.select {|q| !q.match(/network/)}
    # nw_ssids =  wlg.select {|q| q.match(/network/)}
    # aps_tags_ssids.each {|q,v| aps_tags_ssids[q] += nw_ssids.values.first; aps_tags_ssids[q].sort}
    # wlan_ssids_ids = {}
    # self.location_network.wlan_groups.includes(:network_ssids).map {|d| wlan_ssids_ids[d.network_ssids.pluck(:id).sort] = [d.id,d.vendor_id]}

    # aps_tags_ssids.each do |k,v|
    #   wlan_group = wlan_ssids_ids[v]
    #   create_wlan_group unless wlan_group
    # end
  end

  after_destroy do |x|
    if x.location_network.vendor_type == "5"
      Ruckus::ConfigurationService.new(x.location_network).delete_wlan x
    end
    ClientCommunication.where('source_interface = ? or destination_interface = ?',x.id,x.id).each(&:destroy)
    redis_del "ns#{x.id}"
    unless location_network.blank?
      location_network.router_inventories.each(&:update_redis)
    end
  end

  before_save do |ssid|
    ssid.acl_mac_list = ssid.acl_mac_list.try(:upcase)
    self.overwrite_success_url = "false" if self.overwrite_success_url.blank?
    self.nat = "1" if self.nat.blank?
    self.success_url = self.success_url.gsub(/[^[:ascii:]]/, '') unless self.success_url.blank?
    self.splash_url = self.splash_url.gsub(/[^[:ascii:]]/, '') unless self.splash_url.blank?
    self.captive_portal = '0' if self.security_mode == "wpa2"
    (self.dhcp_mappings || []).each_with_index{|a,index| self.dhcp_mappings.delete_at(index) if a['IPADDR'] == '' || a['MAC'] == ''}
    self.radio_bands.delete("")
  end

  before_save do |vlan|
    if vlan.dhcp_relay_server == "1"
      vlan.dhcp_ranges = nil
      vlan.dhcp_lease_time = nil
      vlan.dhcp_mappings = nil
    else
    end  
  end

  def apply_to_network?
    config_mappings.where(resourceable: location_network).any?
  end

  def json_build
    {associated_aps_and_tags: self.associated_aps_and_tags,network_name: location_network.network_name, id: self.id, ssid_name: self.ssid_name, ssid_mode: self.ssid_mode, nat: self.nat, is_enabled: self.is_enabled, is_hidden: self.is_hidden, is_isolate: self.is_isolate, security_mode: self.security_mode, wpa_algorithm: self.wpa_algorithm, wpa_key: self.wpa_key, location_network_id: self.location_network_id, acl_mac: self.acl_mac, mac_filter_policy: self.mac_filter_policy, acl_mac_list: self.acl_mac_list, vlan_id: (self.v_lan.blank? ? "null" : self.v_lan.v_lan_id.to_i), captive_portal: self.captive_portal, splash_url: self.splash_url, wallgarden: nil, walled_garden_range: nil, overwrite_success_url: "false", success_url: nil, dhcp_relay_server: self.dhcp_relay_server, dhcp_lease_time: self.dhcp_lease_time, auth_radius_id: self.auth_radius_id, acc_radius_id: self.acc_radius_id, acc_radius_enabled: self.acc_radius_enabled, ip_address: self.ip_address, subnet_mask: self.subnet_mask, ssid_qos: self.ssid_qos, enable_ssid_qos: self.enable_ssid_qos, per_user_qos: self.per_user_qos, radio_bands: self.radio_bands, max_association: self.max_association, wds_enabled: self.wds_enabled, dns_mode: self.dns_mode, dns_primary: self.dns_primary, dns_secondary: self.dns_secondary, wna: self.wna, dhcp_mappings: self.dhcp_mappings, default_interim_time: self.default_interim_time, default_idle_timeout: self.default_idle_timeout, dhcp_ranges: self.dhcp_ranges, uplink_priority: self.uplink_priority, psk_type: self.psk_type}
  end

  def associated_aps_and_tags
    arr = []
    self.config_mappings.each do |config|
      case config.resourceable_type
      when "LocationNetwork"
        arr << "network:#{config.resourceable_id}"
      when "RouterInventory"
        arr << "AP:#{config.resourceable_id}"
      when "ActsAsTaggableOn::Tag"
        arr << "tag:#{config.resourceable_id}"
      when "HardwareCategory"
        arr << "HWC:#{config.resourceable_id}"
      end
    end

    arr
  end

  def associated_aps_and_tags=(value)
    attribute_will_change!('associated_aps_and_tags') if associated_aps_and_tags != value
    resource_mapping = ConfigMapping::RESOURCE_MAP
    resource_mapping['HWC'] = "HardwareCategory"
    value.delete("")
    exisiting_config = self.associated_aps_and_tags
    new_config = value - exisiting_config
    config_to_remove = exisiting_config - (exisiting_config & value)
    new_config.each do |n|
      self.config_mappings.build( resourceable_type: resource_mapping[n.split(':')[0]], resourceable_id: n.split(':')[1].to_i )
    end
    config_to_remove.each do |n|
      self.config_mappings.where( resourceable_type: resource_mapping[n.split(':')[0]], resourceable_id: n.split(':')[1].to_i ).each(&:destroy)
    end
  end

  def multi_vendor_enablement
    changes_val = self.changes.keys
    arr = ["ssid_name", "is_enabled", "is_hidden","radio_band","security_mode","ssid_mode", "wallgarden","walled_garden_range"]
    changed_values = changes_val.select{|i| arr.include?(i) }
    
    Meraki::Wireless::ConfigurationService.new(self.location_network).update_network_ssid self if changed_values
  end
end
