class VLansController < ApplicationController
  include ChangeNetwork
  before_filter :authenticate_user!
  before_filter :check_network_presence?, only: [:index, :show, :create, :update, :destroy], if: Proc.new { |c| c.request.format.json? }
  before_filter :dashboard_topbar, if: Proc.new { |c| !c.request.format.json? }
  before_action :set_v_lan, only: [:show, :edit, :update, :destroy]
  before_action :find_radius_configuration,only: [:edit,:new]
  load_and_authorize_resource :class => VLan
  check_policy_for :create, :update, :destroy, with: VLan, id_param: :id

  skip_load_resource :only => [:new, :create,:edit,:destroy]

  # GET /v_lans
  # GET /v_lans.json
  def index
    @v_lans = []
    @v_lans = @current_network.v_lans.map {|v| v.json_build }
    if request.format.json?
      render :json => {data: {"vlans" => @v_lans}}
    else
      render :json => @v_lans.map {|d| [d[:id], d[:v_lan_id]]}
    end
  end

  # GET /v_lans/1
  # GET /v_lans/1.json
  def show
    if request.format.json?
      render json: {data: @v_lan.json_build, status: 200}
    end
  end

  # GET /v_lans/new
  def new
    @v_lan = VLan.new :dhcp_lease_time => 86400
    @existing_vlan_ids = @current_network.v_lans.pluck(:v_lan_id).map(&:to_i)
    @vlan_ids = (3..4096).to_a - @existing_vlan_ids
    @vlan_ids = !@existing_vlan_ids.include?(1) ? @vlan_ids.unshift(['Default',1]) : @vlan_ids
    #@offer_string = render_to_string(:template => 'templates/offer_template_one.html.erb', :layout => false)
    #render :text => "v_lans/_form_new.html.erb", :layout => false)
    if request.xhr?
      render :partial => "form_new", :layout => false
    end
  end

  # GET /v_lans/1/edit
  def edit
    @existing_vlan_ids = @current_network.v_lans.pluck(:v_lan_id).map(&:to_i)
    @vlan_ids = (3..4096).to_a - @existing_vlan_ids
    @vlan_ids = !@existing_vlan_ids.include?(1) ? @vlan_ids.unshift(['Default',1]) : @vlan_ids
    #@v_lan_default = @v_lan.v_lan_id == '1'
    if request.xhr?
      render :partial => "form_new", :layout => false
    else
      render :new
    end
    #render :json => {render :partial => "form.html.erb",}
  end

  # POST /v_lans
  # POST /v_lans.json
  def create
    @v_lan = @current_network.v_lans.new(v_lan_params)
    if @v_lan.save
      flash[:success] = "Sucessfully created VLANs"
      json_data = {data: @v_lan.json_build , status: 200}
    else
      json_data = {message: "VLAN is not created. Please check again.", status: 422}
      flash[:error] = "Oops! there was some problem in creating VLANs"
    end
    if request.format.json?
      render json: json_data, status: json_data[:status]
    else
      redirect_to home_path(@current_network)
    end
  end

  # PATCH/PUT /v_lans/1
  # PATCH/PUT /v_lans/1.json
  def update
    if (request.format.json? && params["v_lan"].keys.include?("dhcp_mappings") && params["v_lan"]["dhcp_mappings"].blank?) || (!request.format.json? && params["v_lan"]["dhcp_mappings"].blank?)
      @v_lan.dhcp_mappings = nil
    end
    if (request.format.json? && params["v_lan"].keys.include?("dhcp_ranges") && params["v_lan"]["dhcp_ranges"].blank?) || (!request.format.json? && params["v_lan"]["dhcp_ranges"].blank?)
      @v_lan.dhcp_ranges = nil
    end
    if (request.format.json? && params["v_lan"].keys.include?("dhcp_options") && params["v_lan"]["dhcp_options"].blank?) || (!request.format.json? && params["v_lan"]["dhcp_options"].blank?)
      @v_lan.dhcp_options = nil
    end
    if @v_lan.update(v_lan_params)
      flash[:success] = "Sucessfully updated VLANs"
      json_data = {data: @v_lan.json_build , status: 200}
    else
      flash[:error] = "Oops! there was some problem in updating VLANs"
      json_data = {message: "VLAN is not updated (Reason: #{@v_lan.errors.full_messages}).", status: 422}
      Rails.logger.warn "#{@v_lan.errors.full_messages}"
    end
    if request.format.json?
      render json: json_data, status: json_data[:status]
    else
      redirect_to home_path(@current_network)
    end
  end

  # DELETE /v_lans/1
  # DELETE /v_lans/1.json
  def destroy
    if @v_lan.wired_configs.blank?
      if @v_lan.destroy
        flash[:success] = "Successfully deleted VLANs"
        json_data = {data: {}, status: 200}
      else
        json_data = {message: "VLAN is not deleted. Please try again.", status: 422}
        flash[:error] = "Oops! there was some problem in deleting VLANs"
        Rails.logger.warn "#{@v_lan.errors.full_messages}"
      end
    else
      json_data = {message: "VLAN is not deleted (Reason: You cannot delete the VLAN which is configured on switch. Please deattach it from switch and delete it again)", status: 422}

      flash[:error] = "Sorry! You cannot delete the VLAN which is configured on switch. Please deattach it from switch and delete it again."
    end
    if request.format.json?
      render json: json_data, status: json_data[:status]
    else
      redirect_to home_path(@current_network)
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_v_lan
      if request.format.json?
        @v_lan = @current_network.v_lans.where(:v_lan_id => params[:vlan_id]).first
        if @v_lan.blank?
          render json: {message: "Configuration for requested VLAN ID #{params[:vlan_id]} is not found.", status: 404}, status: 404 
        end
      else
        @v_lan = @current_network.v_lans.where(:id => params[:id]).first
        if @v_lan.blank?
          flash[:notice] = "Requested VLANs not found!"
          redirect_to home_path(@current_network)
        end
      end
    end

    def current_ability
      if Rails.cache.exist?("views/new_sidebar_menu/role_#{current_user.role.id}_#{current_user.is_super_admin}") || Rails.cache.exist?("views/noc_sidebar_menu/role_#{current_user.role.id}_#{current_user.is_super_admin}")
        @current_ability = Ability::VLanAbility.new(current_user)
      else
        @current_ability ||= Ability.new(current_user)
      end
    end

    def change_network
      change_user_network
    end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def v_lan_params
      v_lan_params = params[:v_lan]
      
      base_params = params.require(:v_lan).permit(
        :organisation_id, :network_ssid_id, :v_lan_id, :enable_gre_on_v_lan, 
        :name, :dns_mode, :dhcp_relay_server, :vlan_mode, :wired_mode, :net_mask, 
        :gateway, :dns1, :dns2, :ip_address, :dhcp_lease_time, :wired_config_id, 
        :location_network_id, :nat, :active_scan, :wna, :captive_portal, 
        :splash_url, :wallgarden, :walled_garden_range, :uam_secret, :uam_secret_key, 
        :overwrite_success_url, :success_url, :auth_radius_id, :acc_radius_id, 
        :acc_radius_enabled, :mac_auth, :per_user_qos, :uplink_priority, 
        :enable_vlan_qos, :vlan_qos
      )
      
      [:dhcp_mappings, :dhcp_ranges, :dhcp_options].each do |key|
        string_key = key.to_s
        
        if v_lan_params.key?(string_key)
          param_value = v_lan_params[string_key]
          
          case param_value
          when nil
            base_params[key] = []
          when Array
            if param_value.empty?
              base_params[key] = []
            else
              case key
              when :dhcp_mappings
                base_params[key] = param_value.map { |item| 
                  ActionController::Parameters.new(item).permit(:IPADDR, :MAC) if item.is_a?(Hash)
                }.compact
              when :dhcp_ranges
                base_params[key] = param_value.map { |item| 
                  ActionController::Parameters.new(item).permit(:START, :END) if item.is_a?(Hash)
                }.compact
              when :dhcp_options
                base_params[key] = param_value.map { |item| 
                  ActionController::Parameters.new(item).permit(:CODE, :TYPE, :VALUE) if item.is_a?(Hash)
                }.compact
              end
            end
          end
        end
      end
      base_params
    end
end
