class OpenWifi::ObjectMapper < OpenWifi::BaseApi
  def self.get_device_with_config router_inventory, computed_config=nil
    serialno = OpenWifi::BaseApi.new.mac_to_serialno router_inventory.mac_id
    hw_type = router_inventory.hardware_part.try(:internal_name) || "cig_wf196"
    if router_inventory.location_network.blank?
      {
        name: router_inventory.name || router_inventory.mac_id,
        description: "Created from PCC",
        serialNumber: serialno,
        rrm: "inherit",
        deviceType: hw_type,
        devClass: "any",
        # entity: "",
        # venue: "",
        # subscriber: "",
        __newConfig:     {
          rrm: "inherit",
          firmwareUpgrade: "no",
          firmwareRCOnly: false,
          configuration: [],
          name: "device:#{serialno}",
          description: "Created from PCC",
          deviceTypes: [hw_type]
        }
      }
    else
      {
        name: router_inventory.name || router_inventory.mac_id,
        description: "Created from PCC",
        serialNumber: serialno,
        rrm: "inherit",
        deviceType: hw_type,
        devClass: "any",
        # entity: "",
        # venue: "",
        # subscriber: "",
        __newConfig:     {
          rrm: "inherit",
          firmwareUpgrade: "no",
          firmwareRCOnly: false,
          configuration: get_configuration(router_inventory, computed_config),
          name: "device:#{serialno}",
          description: "Created from PCC",
          deviceTypes: [hw_type]
        }
      }
    end
  end
  
  def self.get_configuration router_inventory, computed_config=nil
    computed_config = get_computed_configuration(router_inventory) unless computed_config
    config = []
    #Globals 
    config << {
                "configuration" => { 
                  "globals" => computed_config["globals"]
                },
                "weight" => 1,
                "description" => "",
                "name" => "Globals"
              }
    #Services
    config << {
                "configuration" => {
                  "services" => computed_config["services"]
                },
                "weight" => 1,
                "description" => "",
                "name" => "Services"
              }
    #RADIO profiles
    radios, desc = get_device_radio_config(router_inventory)
    config << { 
      "name" => "Radios",
      "description" => desc,
      "weight" => 1,
      "configuration" => {
        "radios" => computed_config["radios"]
      }
    }
    #metrics
    config << { 
                "name" => "Metrics",
                "description" => "",
                "weight" => 1,
                "configuration" => {
                  "metrics" => computed_config["metrics"]
                }
              }
    #Interfaces
    #- WAN SSID's
    #- LAN's
    config << { 
                "name" => "Interfaces",
                "description" => "",
                "weight" => 1,
                "configuration" => {
                  "interfaces" => computed_config["interfaces"]
                }
              }
    # config << { 
    #        "name" => "Third Party",
    #        "description" => "",
    #        "weight" => 1,
    #        "configuration" => {
    #          "third-party" => computed_config["third-party"]
    #        }
    #      }
    return config
  end

  def self.get_computed_configuration router_inventory
    interfaces, third_party_cp = get_interfaces_config(router_inventory)
    third_party_cp = third_party_cp.blank? ? {} : third_party_cp.try(:last)
    { 
      "globals" => get_globals_config, 
      "services" => get_services_config(router_inventory).merge(third_party_cp), 
      "radios" => get_device_radio_config(router_inventory)[0], 
      "metrics" => get_device_metrics_config, 
      "interfaces" => interfaces#, 
      # "third-party" => third_party_cp.last 
    }
  end

  def self.get_globals_config
    {
      "ipv6-network" => "::ffff:c0a8:bc01/24",
      "ipv4-network" => "192.168.188.0/24"
    }
  end

  def self.get_services_config router_inventory
    return self.get_services_config_common.merge(self.get_ntp(router_inventory).merge(self.get_services_config_wifi_steering(router_inventory)))
  end

  def self.get_services_config_wifi_steering router_inventory
    return {} if router_inventory.location_network.blank? || router_inventory.get_associated_radio_profile.blank?
    rm = router_inventory.get_associated_radio_profile.radio_management
    radio_management = {"wifi-steering" => {
          "mode" => "local",
          "client-steering" => rm.client_steering,
          "assoc-steering" => rm.assoc_steering,
          "auto-channel-balancing" => rm.auto_channel_balancing,
          "required-probe-snr" => "#{rm.required_probe_snr}".to_i,
          "required-roam-snr" => "#{rm.required_roam_snr}".to_i,
          "load-kick-threshold" => "#{rm.load_kick_threshold}".to_i,
          "required-snr"=> -60
        }}
    return rm.client_steering? ? radio_management : {}
  end

  def self.get_multi_psk ssid
    multi_psk_options = ssid.multi_psk_options
    mpsk = []
    multi_psk_options.each do |m|
        m_psk = {}
        m_psk["key"] = m["PASSPHRASE"]
        m_psk["vlan-id"] = m["v_lan_id"].to_i
        m_psk["mac"] = m["MAC"] if m["MAC"].present? 
        mpsk << m_psk
    end
    return multi_psk_options.present? ? mpsk : {}
  end

  def self.get_roaming ssid
    rmg = ssid.roaming
    return {} if rmg.blank? || !ssid.roaming_mode.eql?("1")
    roaming_hash = {
            "message-exchange" => rmg.message_exchange.to_s,
            "generate-psk" => rmg.generate_psk? ? 1 : 0,
            "domain-identifier" => rmg.domain_identifier.to_s,
            "pmk-r0-key-holder" => rmg.pmk_r0_key_holder.to_s,
            "pmk-r1-key-holder" => rmg.pmk_r1_key_holder.to_s
        }
    return ssid.roaming_mode.eql?("1") ? roaming_hash : {}
  end

  def self.get_rrm
    rrm_hash = { "neighbor-reporting" => true,
            "ftm-responder" =>  true, 
            "stationary-ap" => true
          } 
  end

  def self.get_ntp router_inventory
    ntp = router_inventory.location_network.try(:ntp_server)
    {"ntp" => {
        "local-server" => true,
        "servers" => ntp ? ntp.urls.split(",") : ["0.openwrt.pool.ntp.org"]
      }
    }
  end

  def self.get_services_config_common
    {
      # "http" => {
      #   "http-port" => 80
      # },
      "ssh" => {
        "password-authentication" => true,
        "port" => 22
      }
    }
  end
  
  def self.get_device_radio_config router_inventory
    radio_profile = router_inventory.get_associated_radio_profile
    radios = []
    if radio_profile.present?
      desc = "Custom Radio"
      radios =  radio_profile.radio_settings.map do |rs|
                  next if rs.is_disable
                  config = { "country" => radio_profile.country_code, 
                    "band" => (rs.band.to_i.to_s + "G"),
                    "channel" => (rs.channel == 0 ? 'auto' : rs.channel.to_i),
                    "tx-power" => "#{rs.power}".to_i,
                    #"require_mode" => "#{rs.require_mode}",
                    "channel-width" => rs.bandwidth.to_i,
                    "channel-mode" => rs.require_mode || 'HE',
                    "allow-dfs" => false,
                    "he" => {
                      "ema"=>"#{rs.ema}",
                      "bss-color"=> "#{rs.bss_color}",
                      "multiple-bssid"=>"#{rs.multiple_bssid}"
                    },
                    # "rates"=>{
                    #  "beacon"=>"#{rs.beacon_rate != 'None' ? rs.beacon_rate.to_i : ''}", 
                    #  "multicast"=>"#{rs.multicast != 'None' ? rs.multicast.to_i : ''}" 
                    # },
                    "maximum-clients" => (rs.maximum_clients || 99).to_i
                    # "dtim-period" => (rs.dtim_period || 1).to_i,
                    # "beacon-interval" => (rs.beacon_interval || 15).to_i
                  }
                  if !rs.beacon_interval.blank?
                    config["beacon-interval"] = (rs.beacon_interval || 100).to_i
                  end
                  if !rs.dtim_period.blank?
                    config["dtim-period"] = (rs.dtim_period || 2).to_i
                  end

                  if rs.channel == 0 && rs.valid_auto_channel != "" && !rs.valid_auto_channel.reject(&:blank?).empty?
                    config['valid-channels'] = rs.valid_auto_channel.reject(&:blank?).map{|x| x.to_i}
                    config["allow-dfs"] = true
                  end
                  if rs.beacon_rate != 'None' || rs.multicast != 'None'
                   config['rates'] = {}
                   config['rates']['beacon'] = rs.beacon_rate.to_i if rs.beacon_rate != 'None'
                   config['rates']['multicast'] = rs.multicast.to_i if rs.multicast != 'None'
                  end

                  config
                end
    else
      #TODO: default radio config
      desc = "PCC Default"
      radios = [
                {
                  "band" => "2G",
                  "channel" => 6,
                  "channel-width" => 20,
                  "country" => "US",
                  "tx-power" => 0,
                  "beacon-interval" => 100,
                  "dtim-period" => 5
                },
                {
                  "band" => "5G",
                  "channel" => 36,
                  "channel-width" => 80,
                  "country" => "US",
                  "tx-power" => 0,
                  "beacon-interval" => 100,
                  "dtim-period" => 12
                }
              ]
    end
    
    return [radios.compact, desc]
  end

  def self.get_device_metrics_config
    {
      "dhcp-snooping" => {
        "filters" => [
          "ack",
          "discover",
          "offer",
          "request",
          "solicit",
          "reply",
          "renew"
        ]
      },
      "wifi-frames" => {
        "filters" => [
          "probe"
          # "auth",
          # "assoc",
          # "disassoc",
          # "deauth",
          # "local-deauth",
          # "inactive-deauth",
          # "key-mismatch",
          # "beacon-report",
          # "radar-detected"
        ]
      },
      "health" => {
        "interval" => 60
      },
      "statistics" => {
        "types" => [
          "ssids",
          "lldp",
          "clients"
        ],
        "interval" => 60
      }
    }
  end

  def self.get_interfaces_config router_inventory
    upstream_ssids_config = []
    vlan_upstream_ssids_config = []
    downstream_ssids_config = []
    vlan_downstream_ssids_config = []
    vlan_downstream_wired_configs = []
    vlan_upstream_wired_configs = []
    interfaces = []
    cp_vlan = []
    associated_ssids = router_inventory.get_all_associated_ssids
    associated_wired_config = router_inventory.get_all_associated_wired_config
    org = router_inventory.organisation

    associated_ssids.each do |ssid|
      next unless ssid.is_enabled
      encryption = {
                    "proto" => (ssid.multi_psk == 'radius' && ssid.security_mode =="psk2") ? "psk2-radius" : ssid.security_mode, #wpa, psk
                    "ieee80211w" => (ssid.radio_bands.blank? || !ssid.radio_bands.include?("6")) ? "optional" : "required"
                  }
      encryption['key'] = ssid.wpa_key if encryption['proto'] == 'psk2' || encryption['proto'] == 'sae'
      radio_bands = ssid.radio_bands.map {|s| s.to_i.to_s + "G" }#ssid.radio_band == "both" ? ["2G", "5G"] : [ssid.radio_band.to_i.to_s + "G"]
      ssid_config = {
        "name" => ssid.ssid_name,
        "hidden-ssid" => ssid.is_hidden,
        "bss-mode" => ssid.wds_enabled ? "wds-ap" : "ap", #"ap", "sta", mesh", "wds-ap", "wds-sta", "wds-repeater" 
        "wifi-bands" => radio_bands, #"2G", "5G", "5G-lower", "5G-upper", "6G"
        "maximum-clients" => ssid.max_association == 0 ? 99 : ssid.max_association,
        "isolate-clients" => ssid.is_isolate,
        "power-save" => ssid.power_save.blank? ? false : ssid.power_save,
        "services" => [
          "wifi-frames", "ntp", "wifi-steering"
        ],
        "encryption" => encryption
      }

      #radius gateway proxy
      if ssid.security_mode == 'psk2' && ssid_config['encryption']['proto'] == 'psk2-radius' && ssid.radius_gw_proxy && ssid.captive_portal.to_i == 0
        ssid_config['services'] << 'radius-gw-proxy'
      end

      #SSID Rate limit - QoS
      if ssid.enable_ssid_qos
        limit = ssid.ssid_qos.to_i / 1024
        ssid_config["rate-limit"] = {
          "ingress-rate" => limit,
          "egress-rate" => limit
        }
      end

      #ACL policies
      if ssid.acl_mac == "1"
        ssid_config['access-control-list'] = {
          "mode" => ssid.mac_filter_policy == "1" ? "allow" : "deny",
          "mac-address" => ssid.acl_mac_list.split(",")
        }
      end

      roaming = self.get_roaming(ssid)
      ssid_config["roaming"] = roaming unless roaming.blank?

      if ssid.security_mode == 'wpa2' || ssid.security_mode == 'wpa3'
        radius = self.get_radius_config(ssid,router_inventory)
        ssid_config["radius"] = radius
      end

      if ssid.security_mode == 'psk2' && ssid.multi_psk == 'local'
        multi_psk = self.get_multi_psk ssid
        ssid_config["multi-psk"] = multi_psk unless multi_psk.blank?
      end

      if ssid.security_mode == 'psk2' && ssid.multi_psk == 'radius'
        radius = self.get_radius_config(ssid,router_inventory)
        ssid_config["radius"] = radius
      end
      
      rrm = self.get_rrm
      ssid_config["rrm"] = rrm if ssid.ssid_802_11_k?
         
      if ssid.ssid_mode == "0"
        ssid_vlan = ssid.v_lan
        if ssid_vlan.present? && ssid_vlan.v_lan_id.to_i > 0 #&& ssid_vlan.location_network_id.present?
          v_lan = router_inventory.location_network.v_lans.where(v_lan_id: ssid_vlan.v_lan_id).last
          if v_lan
            vlan_downstream_ssids_config << [v_lan, ssid_config]
            if v_lan.captive_portal.to_i != 0
              # cp_vlan << get_third_party_CP_services(router_inventory, v_lan)
              cp_vlan << get_newest_third_party_CP_services(router_inventory, v_lan)
              #ssid_config['services'] << "chilli-redirect"
              ssid_config['services'] << "captive"
            end
          else
            vlan_upstream_ssids_config << [ssid_vlan.v_lan_id, ssid_config]
            if ssid.captive_portal.to_i != 0
              # cp_vlan << get_third_party_CP_services(router_inventory, ssid) 
              cp_vlan << get_newest_third_party_CP_services(router_inventory, ssid)
              # ssid_config['services'] << "chilli-redirect"
              ssid_config['services'] << "captive"
            end
          end
        else
          upstream_ssids_config << ssid_config
          if ssid.captive_portal.to_i != 0
            # cp_vlan << get_third_party_CP_services(router_inventory, ssid) 
            cp_vlan << get_newest_third_party_CP_services(router_inventory, ssid)
            # ssid_config['services'] << "chilli-redirect"
            ssid_config['services'] << "captive"
          end
        end
      else
        ssid_config['role'] = 'downstream'
        downstream_ssids_config << [ssid, ssid_config]
        if ssid.captive_portal.to_i != 0
          # cp_vlan << get_third_party_CP_services(router_inventory, ssid) 
          cp_vlan << get_newest_third_party_CP_services(router_inventory, ssid)
          # ssid_config['services'] << "chilli-redirect"
          ssid_config['services'] << "captive"
        end
      end
    end

   #WIRED CONFIG 


    wired_config = associated_wired_config
    if wired_config.present? && wired_config.custom_port != '1'
      ethernet = []
      wan_port_vlans = wired_config.port_configs.select {|d| d['PID'] == '1' }.first
      
      vlans = wired_config.port_configs.select {|d| d['DIS'] != '1' }.map {|d| ([d['PVID']]+d['VID']).uniq.compact}

      vlan_mapping = {}
      wired_config.port_configs.select {|d| d['DIS'] != '1'}.each do |port_config|
        if port_config['PVID'].present?
          vlan_mapping[port_config['PVID']] ||= []
          ethernet_conf = {}
          ethernet_conf['select-ports'] ||= []
          # ethernet_conf['select-ports'] << (port_config['PID'] == '1' ? "WAN*" : "LAN#{port_config['PID'].to_i-1}")
          ethernet_conf['select-ports'] << (port_config['PID'] == '1' ? "WAN*" : "LAN*")
          if port_config['TAG'].to_i == 1 && (port_config['VID']||[]).include?(port_config['PVID'])
            ethernet_conf['vlan-tag'] = "tagged"
          else
            ethernet_conf['vlan-tag'] = "un-tagged"
          end
          # ethernet_conf['pvid'] = true if port_config['TAG'] == '1' && !(port_config['VID']||[]).include(port_config['PVID']
          vlan_mapping[port_config['PVID']] << ethernet_conf
        end

        if port_config['TAG'].to_i == 1 && port_config['VID'].present?
          port_config['VID'].first.split(',').each do |vid|
            vlan_mapping[vid] ||= []
            ethernet_conf = {}
            ethernet_conf['select-ports'] ||= []
            # ethernet_conf['select-ports'] << (port_config['PID'] == '1' ? "WAN*" : "LAN#{port_config['PID'].to_i-1}")
            ethernet_conf['select-ports'] << (port_config['PID'] == '1' ? "WAN*" : "LAN*")
            # ethernet_conf['vlan-tag'] = "un-tagged"
            vlan_mapping[vid] << ethernet_conf
          end
        end
      end

      vlan_mapping.each do |vlan_id, ethernet_conf|
        v_lan = router_inventory.location_network.v_lans.where(v_lan_id: vlan_id.to_i).last
        if v_lan.present?
          vlan_downstream_wired_configs << [ethernet_conf,v_lan]
          # if v_lan.captive_portal.to_i != 0
          #   # cp_vlan << get_third_party_CP_services(router_inventory, v_lan)
          #   cp_vlan << get_newest_third_party_CP_services(router_inventory, v_lan)
          #   #ssid_config['services'] << "chilli-redirect"
          #   ssid_config['services'] << "captive"
          # end
        else
          # vlan_upstream_wired_configs << [ethernet_conf, pvid.to_i]
          vlan_upstream_wired_configs << [ethernet_conf, vlan_id.to_i]
        end
      end 

      # wired_config.port_configs.select {|d| d['DIS'] != '1' && d['PID'] != '1' }.group_by {|d| d['PVID'].to_i }.each do |pvid, port_configs|
      #   ethernet << {"select-ports" => ["WAN*"]}
      #   selected_ports = []
      #   v_lan = router_inventory.location_network.v_lans.where(v_lan_id: pvid.to_i).last
      #   if wired_config.custom_port == "2"
      #     selected_ports << "LAN*"
      #   elsif wired_config.custom_port == "3"
      #     port_configs.each do |port_config|
      #       selected_ports << "LAN#{port_config['PID'].to_i + 1}"
      #     end
      #   end
      #   if v_lan.present?
      #     vlan_downstream_wired_configs << [selected_ports,v_lan]
      #     # if v_lan.captive_portal.to_i != 0
      #     #   # cp_vlan << get_third_party_CP_services(router_inventory, v_lan)
      #     #   cp_vlan << get_newest_third_party_CP_services(router_inventory, v_lan)
      #     #   #ssid_config['services'] << "chilli-redirect"
      #     #   ssid_config['services'] << "captive"
      #     # end
      #   else
      #     vlan_upstream_wired_configs << [selected_ports, pvid.to_i]
      #   end
      # end
    end
    ipv4_s = {
        "addressing" => "dynamic"
      }
    ipv4_s = {
        "addressing" => "static",
        "gateway"=> "156.0.213.83",
        "send-hostname"=> true,
        "subnet"=> "156.0.213.86/28",
        "use-dns"=> ["8.8.8.8","8.8.4.4"]
      } if router_inventory.mac_id == "E0:01:A6:6C:76:E8" # TODO: Remove this after implementing the static in UI

    #WAN Bridge mode SSID's without vlan
    interfaces << {
      "name" => "WAN",
      "role" => "upstream",
      "services" => ['ntp', 'ssh'],
      "ethernet" => [
        {
          "select-ports" => [
            "WAN*"
          ]
        }
      ],
      "ipv4" => ipv4_s,
      "ssids" => upstream_ssids_config
    }

    #LAN with router SSID's NAT
    downstream_ssids_config.each do |ssid, ssid_config|
      ipv4 = {
        "addressing" => "static",
        "subnet" => "#{ssid.ip_address}#{self.mask_2_ciddr(ssid.subnet_mask)}"
      }
      ipv4["dhcp"] = {
        "lease-first" => (((ssid.dhcp_ranges||[]).first || {})['START'] || "10").split('.').last.to_i,
        "lease-count" => 250,
        "lease-time" => "#{ssid.dhcp_lease_time.to_i}s"
      } if ssid.dhcp_relay_server == "2"
      interfaces << {
          "name" => "LAN",
          "role" => "downstream",
          "services" => ['ntp'],
          "ethernet" => [
            {
              "select-ports" => [
                "LAN*"
              ]
            }
          ],
          "ipv4" => ipv4,
          "ssids" => [ssid_config]
        }
    end

    #WAN bridge mode SSID's with vlan_id
    vlan_upstream_ssids_config.group_by {|d| d[0] }.each do |vlan_id, ssids|
      interfaces << {
        "name" => "WAN VLAN#{vlan_id}",
        "role" => "upstream",
        "services" => ['ntp', 'ssh'],
        "vlan" => {
          "id" => vlan_id.to_i
        },
        "ethernet" => [
          {
            "select-ports" => [
              "WAN*"
            ]
          }
        ],
        "ipv4" => ipv4_s,
        "ssids" => ssids.map(&:last)
      }
    end

    #LAN bridge mode SSID's with vlan config
    if vlan_downstream_ssids_config
      vlan_downstream_ssids_config.group_by {|d| d[0]}.each do |v_lan, downstream_ssids|
        ipv4 = {
            "addressing" => "static",
            "subnet" => "#{v_lan.ip_address}#{self.mask_2_ciddr(v_lan.net_mask)}"
          }
        ipv4["dhcp"] = {
          "lease-first" => (((v_lan.dhcp_ranges||[]).first || {})['START'] || "10").split('.').last.to_i,
          "lease-count" => 100,
          "lease-time" => "#{v_lan.dhcp_lease_time.to_i}s"
        } if v_lan.dhcp_relay_server == "2"
        interfaces << {
          "name" => "LAN VLAN#{v_lan.v_lan_id}",
          "role" => "downstream",
          "services" => ['ntp'],
          "vlan" => {
              "id" => v_lan.v_lan_id.to_i
          },
          "ethernet" => [
            {
              "select-ports" => [
                "LAN*"
              ]
            }
          ],
          "ipv4" => ipv4,
          "ssids" => downstream_ssids.map(&:last)
        }
      end
    end

    vlan_upstream_wired_configs.each do |selected_ports, vlan_id|
      interfaces << {
        "name" => "WAN VLAN#{vlan_id}",
        "role" => "upstream",
        # "services" => ['ntp', 'ssh'],
        "vlan" => {
          "id" => vlan_id.to_i
        },
        "ethernet" => selected_ports
      }
    end


    #LAN bridge mode Wired config's with vlan config
    if vlan_downstream_wired_configs
      vlan_downstream_wired_configs.each do |selected_ports, v_lan|
        ipv4 = {
            "addressing" => "static",
            "subnet" => "#{v_lan.ip_address}#{self.mask_2_ciddr(v_lan.net_mask)}"
          }
        ipv4["dhcp"] = {
          "lease-first" => (((v_lan.dhcp_ranges||[]).first || {})['START'] || "10").split('.').last.to_i,
          "lease-count" => 100,
          "lease-time" => "#{v_lan.dhcp_lease_time.to_i}s"
        } if v_lan.dhcp_relay_server == "2"
        interfaces << {
          "name" => "LAN VLAN#{v_lan.v_lan_id.to_i}",
          "role" => "downstream",
          "services" => ['ntp'],
          "vlan" => {
              "id" => v_lan.v_lan_id.to_i
          },
          "ethernet" => selected_ports,
          "ipv4" => ipv4
        }
      end
    end
    
    [interfaces, cp_vlan]
  end

  def self.get_newest_third_party_CP_services router_inventory, cp_obj
    radius_auth = cp_obj.radius_authentication
    radius_acc = cp_obj.radius_accounting
    cp_ssids =
    {
      "captive" => {
        "auth-mode"=> "uam",
        "uam-port" => 3990,
        "auth-port" => radius_auth.try(:radius_port).try(:to_i),
        "acct-port" => radius_acc.try(:radius_port).try(:to_i),
        "auth-server" => radius_auth.try(:radius_ip),
        "acct-server" => radius_acc.try(:radius_ip),
        "nasid" => router_inventory.mac_id,
        "walled-garden-fqdn" => (cp_obj.walled_garden_range||"").split(","),
        "idle-timeout" => cp_obj.default_idle_timeout.to_i,
        "acct-interval" => cp_obj.default_interim_time.to_i,
        "uam-server" => cp_obj.splash_url,
        "auth-secret" => radius_auth.try(:radius_secret),
        "acct-secret" => radius_acc.try(:radius_secret),
        "mac-auth" => (cp_obj.mac_auth == 1 ? true : false)
      }
    }
    cp_ssids["captive"]["radius-gw-proxy"] = cp_obj.radius_gw_proxy if cp_obj.radius_gw_proxy
    cp_ssids["captive"]["uam-secret"] = cp_obj.uam_secret_key if cp_obj.uam_secret
    return cp_ssids
  end


  def self.get_third_party_CP_services router_inventory, cp_obj
    radius_auth = cp_obj.radius_authentication
    radius_acc = cp_obj.radius_accounting
    cp_ssids = 
    {
      "chilli-redirect" => {
        "uamport" => 3990,
        "radiusauthport" => radius_auth.try(:radius_port).try(:to_i),
        "radiusacctport" => radius_acc.try(:radius_port).try(:to_i),
        "radiusserver1" => radius_auth.try(:radius_ip),
        # "radiusserver2" => "radiusServerIP",
        "radiusnasid" => router_inventory.mac_id,
        "uamallowed" => cp_obj.walled_garden_range,
        "uamdomain" => "captive.wavespot.ai",
        "defidletimeout" => cp_obj.default_idle_timeout.to_i,
        "definteriminterval" => cp_obj.default_interim_time.to_i,
        "acctupdate" => cp_obj.acc_radius_enabled.to_i,
        "uamserver" => cp_obj.splash_url,
        "radiussecret" => radius_auth.try(:radius_secret),
        "nasmac" => router_inventory.mac_id
      }
    }
  end

  def self.old_get_third_party_CP_services router_inventory, cp_obj
    radius_auth = cp_obj.radius_authentication
    radius_acc = cp_obj.radius_accounting
    cp_ssids = 
    {
      "captive" => {
        "uamport" => 3990,
        "radiusauthport" => radius_auth.try(:radius_port).try(:to_i),
        "radiusacctport" => radius_acc.try(:radius_port).try(:to_i),
        "radiusserver1" => radius_auth.try(:radius_ip),
        # "radiusserver2" => "radiusServerIP",
        "radiusnasid" => router_inventory.mac_id,
        "uamallowed" => cp_obj.walled_garden_range,
        "uamdomain" => "captive.wavespot.ai",
        "defidletimeout" => cp_obj.default_idle_timeout.to_i,
        "definteriminterval" => cp_obj.default_interim_time.to_i,
        "acctupdate" => cp_obj.acc_radius_enabled.to_i,
        "uamserver" => cp_obj.splash_url,
        "radiussecret" => radius_auth.try(:radius_secret),
        "nasmac" => router_inventory.mac_id
      }
    }
  end

  def self.get_radius_config ssid,router_inventory=nil
    radius = {}
    radius_auth = ssid.radius_authentication
    radius_acc = ssid.radius_accounting
    radius["nas-identifier"] = router_inventory.mac_id unless router_inventory.blank?
    radius["authentication"] = {
        "host" => radius_auth.radius_ip,
        "port" => radius_auth.radius_port.to_i,
        "secret" => radius_auth.radius_secret
      } if radius_auth.present?

    radius["accounting"] = {
        "host" => radius_acc.radius_ip,
        "port" => radius_acc.radius_port.to_i,
        "secret" => radius_acc.radius_secret
      } if radius_acc.present?

    radius
  end

  def self.get_radius_proxy_config ssid
    radius_auth = ssid.radius_authentication
    radius_acc = ssid.radius_accounting

    params = { 
            "description"=>"[RAD-ACC-#{radius_acc.try(:id)} | RAD-AUTH-#{radius_auth.try(:id)}] pool",
            "name"=>"RAD-ACC-#{radius_acc.try(:id)}|RAD-AUTH-#{radius_auth.try(:id)}", 
            "useByDefault"=>false
            }
    if radius_acc.present?
      params["acctConfig"] =
            {
              "methodParameters"=>[], 
              "monitor"=>false, 
              "monitorMethod"=>"none", 
              "servers"=>[
                {
                  "ip"=>radius_acc.radius_ip, 
                  "name"=>"[RAD-ACC-#{radius_acc.id}]" + radius_acc.radius_name, 
                  "port"=>radius_acc.radius_port.to_i,
                  "weight"=>100, 
                  "secret"=>radius_acc.radius_secret
                }
              ], 
              "strategy"=>"random"
            }
    end
    if radius_auth.present?
      params["authConfig"] =
            {
              "methodParameters"=>[], 
              "monitor"=>false,
              "monitorMethod"=>"none", 
              "servers"=>[
                {
                  "ip"=>radius_auth.radius_ip, 
                  "name"=>"[RAD-AUTH-#{radius_auth.id}]" + radius_auth.radius_name, 
                  "port"=>radius_auth.radius_port.to_i, 
                  "weight"=>100, 
                  "secret"=>radius_auth.radius_secret
                }
              ], 
              "strategy"=>"random"
            }
    end

    params
  end


  def self.get_switch_port_configuration router_inventory
    switch_conf = router_inventory.get_associated_switch_configuration
    return {} if switch_conf.blank? || switch_conf.switch_port_configurations.blank?
    ports_conf = switch_conf.switch_port_configurations
    ethernet = []
    interfaces = []
    switch_config = {}
    vlan_mapping = {}
    firmware_version = $redis.hget("AP:#{router_inventory.mac_id}", "version")
    ports_conf.each do |port|
      port_attr = port.port_attributes
      #NOTE: Above Firmware 2.8.5.232 we need to send it in 'poe' instead of 'poe-port'
      port_attr['poe'] = port_attr.delete("poe-port") if port.is_poe_port? && firmware_version.present? && firmware_version.gsub(/\D/,'') > "2.8.5.232".gsub(/\D/,'')
      ethernet << port_attr 
      port.interface_vlan_hash vlan_mapping
    end
    interfaces  = switch_conf.interface_attributes vlan_mapping
    switch_config["interfaces"] = interfaces
    switch_config["ethernet"] = ethernet
    switch_config["metrics"] = {"dhcp-snooping" => {"filters" => ["ack","discover","offer","request","solicit","reply","renew"]},"health" => {"interval" => 60},"statistics" =>  {"interval" =>  60,"types" =>  []}}
    switch_config["unit"] = {"leds-active" => true,"usage-threshold" => 95}
     switch_config["services"] = {"http"=>{"enabled"=>!router_inventory.enable_pci},"ssh"=>{"enabled"=>!router_inventory.enable_pci}, "telnet"=>{"enabled"=>!router_inventory.enable_pci},"console-password"=>"tM538kh3@bMq1AU0"}
#    switch_config["services"]["mac-based-vlan"] = switch_conf.get_mac_based_vlan 
    return switch_config, []
  end



  private

  def self.mask_2_ciddr mask
    return "" if mask.blank?
    
    "/" + mask.split(".").map { |e| e.to_i.to_s(2).rjust(8, "0") }.join.count("1").to_s
  end
end
