class ConfigurationController < ApplicationController
  include ChangeNetwork
  before_action :authenticate_user!
  before_action :check_permission, only: [:ap_diagonstic]
  before_action :dashboard_topbar
  before_action :find_radius_configuration, :only => [:new, :edit]
  before_action :find_vlans, :only => [:new, :edit]
  before_action :set_network_ssid, :only => [:edit, :update]
  load_and_authorize_resource :class => NetworkSsid, :except => [:ap_diagonstic]
  check_policy_for :update, with: NetworkSsid, id_param: :id
  skip_load_resource :only => [:new, :create,:get_ap_ssid,:change_network]
  
  def new
    @network_ssid = @current_network.network_ssids.build(APPLICATION["defaults"]["configure_default_val"])
  end

  def show
    redirect_to home_path(@current_network) if params[:id].blank?
    @network_ssid = @current_network.network_ssids.find_by_id(params[:id])
    redirect_to home_path(@current_network)
  end

  def index
  end

  def update
    if !netork_ssid_params.key?(:dhcp_ranges) && !netork_ssid_params.key?(:dhcp_mappings) && !netork_ssid_params.key?(:dhcp_options)
      network_ssid_params = netork_ssid_params.merge!(:dhcp_ranges => [], :dhcp_mappings => [], :dhcp_options => [])
    elsif !netork_ssid_params.key?(:dhcp_ranges)
      network_ssid_params = netork_ssid_params.merge!(:dhcp_ranges => [])
    elsif !netork_ssid_params.key?(:dhcp_mappings)
      network_ssid_params = netork_ssid_params.merge!(:dhcp_mappings => [])
    elsif !netork_ssid_params.key?(:dhcp_options)
      network_ssid_params = netork_ssid_params.merge!(:dhcp_options => [])
    else
      network_ssid_params = netork_ssid_params
    end
    
    if @network_ssid.update_attributes(network_ssid_params)
      flash[:success] = "Successfully updated Network SSID #{@network_ssid.ssid_name}"
    else
      flash[:error] = "Oops! there was some problem in updating Network SSID"
      Rails.logger.warn "#{@network_ssid.errors.full_messages}"
    end
    redirect_to home_path(@current_network)
  end

  def create
    if @current_network.network_ssids.create(netork_ssid_params)
      flash[:success] = "Successfully created new Network SSID"
    else
      flash[:error] = "Oops! there was some problem in creating Network SSID"
    end
    redirect_to home_path(@current_network)
  end

  def edit
    redirect_to home_path(@current_network)  unless @current_network.id.to_i.eql?params[:home_id].to_i
    redirect_to home_path(@current_network) if params[:id].blank?
    @network_ssid = @current_network.network_ssids.find_by_id(params[:id])
  end

  def destroy
    redirect_to  home_path(@current_network) and return if params[:id].blank?
    if @current_network.network_ssids.count > 1
      a = @current_network.network_ssids.find_by_id(params[:id])
      unless a.blank?
        if a.destroy
          flash[:success] = "Successfully deleted Network SSID #{a.ssid_name}"
        else
          flash[:notice] = "Oops! Requested  Network SSID is not found"
          Rails.logger.warn "#{a.errors.full_messages}"
        end
      else
        flash[:warning] = "Requested Network SSID is not found in this network!"
      end
    end
    redirect_to  home_path(@current_network) and return
  end

  def change_ssid_state
    render :json=> {:status=>false,:reload => false}.to_json and return if params[:id].blank?
    network_ssid =  @current_network.network_ssids.where(:id => params[:id]).first
    render :json=> {:status=>'notice',:msg=>"Oops! Requested Network SSID not found since the network got changed so page will be refreshed in 5 seconds",:reload => true,:id => "#{@current_network.id}"}.to_json and return if network_ssid.blank?
    network_ssid.is_enabled = params[:is_enabled] || true
    if network_ssid.save!
      render :json=> {:status=>'success',:msg=>'Successfully updated Network SSID',:reload => false}.to_json and return
    else
      render :json=> {:status=>'error',:msg=>'Oops! Problem updating Network SSID Please try after some time',:reload => false}.to_json and return
    end
  end

  def verify_ip
    #case params[:verify_for]
    #when "network_ssid"
      network = @current_network.network_ssids.on_router_mode.find_by_ip_address(params[:ip_address])
      network_status = network.blank? || network.id.to_s.eql?(params[:network_ssid]) ? true : false
    #when "wired_config"
      wc = @current_network.v_lans.find_by_ip_address(params[:ip_address])
      wired_status = wc.blank? || wc.id.to_s.eql?(params[:wired_config]) ? true : false
    #else
      #status = false
    #end
    status = network_status && wired_status
    render :json => {value: status}
  end

  def bulk_update
  end

  def ap_diagonstic
    unless @current_network.blank?
       mac = []
       routers = @current_network.router_inventories
       @inventory_up_list = RouterInventory.find_up_list(routers.pluck(:mac_id), RouterInventory.get_hb_intreval(@current_network.hb_freq))
       @mac = []
       routers.each do |ri|
         r = $redis.hgetall "AP:#{ri.mac_id}"
         version = r['version'].present? ? r["version"].split('.').join() : '0'
        if ri.name.present?
          @mac << ["#{(@inventory_up_list.include?(ri.mac_id) ? '<i class=fa fa-arrow-up text-success>' : '<i class=fa fa-arrow-down text-danger>')} </i>".html_safe + "#{ri.name}(#{ri.mac_id.split(':').last(3).join(':')})",ri.mac_id,version]
        else
          @mac << [ri.mac_id,ri.mac_id,version]
        end
      end
    end
  end

  def get_ap_ssid
    ap = RouterInventory.find_by_mac_id(params[:mac])
    hash = {}
    unless ap.blank?
      ssids = ap.get_associated_network_ssids
      hash["SSID"] = ssids.map{|a| [a.id,a.ssid_name]} unless ssids.blank?
      wired_config = ap.associated_wired_config
      wired_config = ap.location_network.associated_wired_config unless wired_config.present?
      hash["WIRED"] = [[wired_config.id,wired_config.name]] if wired_config.present?
      hash["UPLINK"] = ap.uplinks.pluck(:id,:uplink_name)
      hash["VENDOR_TYPE"] = ap.vendor_type
    end
    render :json => hash

  end

  def initiate_trace 
    mac_id = params[:mac]
    ri = RouterInventory.where(mac_id: mac_id).last
    res = OpenWifi::ProvisioningService.new(ri.try(:location_network), ri.organisation, ri).trace mac_id
    render :json => res
  end

  def download_trace
    mac_id = params["mac_id"]
    uuid = params["uuid"]
    ri = RouterInventory.where(mac_id: mac_id).last
    data = OpenWifi::ProvisioningService.new(ri.try(:location_network), ri.organisation, ri).file mac_id, uuid
    send_data( data, :filename => "#{mac_id.gsub(':','')}_trace.pcap" )
  end

  def change_network 
    change_user_network
  end

  private

    def netork_ssid_params
      params.require(:network_ssid).permit(:ssid_name,:is_enabled,:ssid_mode,:nat,:wna,:is_hidden,:is_isolate,:security_mode,:wpa_algorithm,:wpa_key,:psk_type, :multi_psk,:auth_radius_id,:mac_auth,:acc_radius_enabled,:acc_radius_id,:acl_mac,:mac_filter_policy,:acl_mac_list,:captive_portal,:splash_url,:wallgarden,:walled_garden_range,:overwrite_success_url,:success_url,:uam_secret,:uam_secret_key,:dhcp_range_start,:dhcp_range_end,:dhcp_relay_server,:dhcp_lease_time,:ip_address,:subnet_mask, :per_user_qos, :enable_ssid_qos, :ssid_qos, :wds_enabled, :power_save, :ssid_802_11_k, :max_association, :dns_mode, :dns_primary, :dns_secondary , :default_idle_timeout, :default_interim_time, :uplink_priority, :band_steering, :ssid_802_11_w, :radius_gw_proxy, :associated_aps_and_tags => [], :radio_bands => [], :dhcp_mappings => [:IPADDR,:MAC],:dhcp_ranges => [:START,:END],:dhcp_options => [:CODE,:TYPE,:VALUE],:multi_psk_options => [:v_lan_id,:PASSPHRASE,:MAC],:v_lan_attributes => [:name,:enable_dhcp_on_v_lan,:v_lan_id, :id], :roaming_attributes => [:message_exchange, :domain_identifier, :pmk_r1_type, :pmk_r0_type, :pmk_r1_key_holder, :generate_psk, :pmk_r0_key_holder, :network_ssid_id, :organisation_id, :id], :hotspot20_attributes => [:hotspot_2_0, :operator_name, :venue_name, :venue_operator_language_code, :network_type, :internet, :domain_list, :roaming_consortium_oi, :network_ssid_id, :id, :_destroy, :nai_realms_attributes => [:realm_name, :realm_format, :gpp_plmn_id, :hotspot20_id, :gpp_plmn_id, :id, :_destroy, :authentication => []], :venue_type => []])
    end

    def find_radius_configuration
      @r_config = current_user.organisation.radiuses
      @r_acc = current_user.organisation.radius_accountings
      @aps_collection = @current_network.grouped_collection_of_ap_and_tags
    end

    def find_vlans
      @v_lans = current_user.organisation.v_lans rescue []
      @radio_profiles = current_user.organisation.radio_profiles rescue []
    end

    def set_network_ssid
      unless @current_network.id.to_i.eql? params[:home_id].to_i
        flash[:notice] = "Your network has been changed to #{@current_network.network_name}. Please try again!"
      end
      @network_ssid = @current_network.network_ssids.where(:id => params[:id]).first
      unless @network_ssid.present?
        flash[:notice] = "Requested Network SSID is not found for current network."
      end
      redirect_to home_path(@current_network) unless flash.blank?
    end

    def check_permission
      if ["monitor_only"].include? @current_user.role.try(:name)
        raise CanCan::AccessDenied.new("You are not authorized to perform this action!")
      end
    end
end
