class LoggingController < ApplicationController
  include ChangeNetwork
  before_filter :authenticate_user!
  before_filter :dashboard_topbar
  load_and_authorize_resource :class => Logging,:except => [:showing_tag,:change_network,:event_logging, :filter_event_logging]
  load_and_authorize_resource :class => EventLogging,:only => [:event_logging]
  skip_load_resource :only => [:create,:update,:event_logging, :change_network]
  check_policy_for :create, :update, :destroy, with: Logging, id_param: :id

  def index
    unless @current_network.blank?
      @aps_collection = []
      if params[:id].blank?
        @logging = @current_network.loggings.new
      else
         @logging = @current_network.loggings.find_by_id(params[:id])
         @aps_collection = @current_network.grouped_collection_of_ap_and_tags
      end
      @loggings = Logging.where(:location_network_id => @current_network.id)
      @event_enabled = @loggings.where(:location_network_id => @current_network.id,logging_type: 'event_logging').present? ? 1 : 0
    end
  end

  def create
    @logging = @current_network.loggings.new(logging_params)
    respond_to do |format|
      if @logging.save
        flash[:success] = "Successfully created Logging details"
        format.json { render action: 'create', status: :created, location: @logging}
        format.html { redirect_to logging_index_path}
      else
        flash[:error] = "Oops! there was some problem in creating Logging details"
        format.html { render action: 'new' }
        format.json { render json: @logging.errors, status: :unprocessable_entity }
      end
    end
    # redirect_to logging_index_path
  end

  def update
    @logging = @current_network.loggings.find_by_id(params[:id])
    respond_to do |format|
      if @logging.update(logging_params)
        flash[:success] = "Successfully updated Logging details"
        format.json        
        format.html { redirect_to logging_index_path }
      else
        flash[:error] = "Oops! there was some problem in updating Logging details"
        format.html { render action: 'edit' }
        format.json { render json: @logging.errors, status: :unprocessable_entity }
      end
    end
  end

  def showing_tag
    @ris = RouterInventory.get_all_based_on_tag(params[:id])
  end

  def updatus_enabled_status
     render :json=> {:status=>false,:reload => false}.to_json and return if params[:id].blank?
     logging =  @current_network.loggings.find_by_id(params[:id])
    render :json=> {:status=>'notice',:msg=>"Oops! Requested Logging 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 logging.blank?
    value = params[:is_enabled] == 'true' ? 1 : 0
    if logging.update_attributes({:is_enabled => value })
      render :json=> {:status=>'success',:msg=>'Successfully updated Logging',:reload => false}.to_json and return
    else
      render :json=> {:status=>'error',:msg=>'Oops! Problem updating Logging Please try after some time',:reload => false}.to_json and return
    end
  end

  def get_selected_associated_resources
    resources = @current_network.loggings.where.not(:id => params[:logging_id]).where(logging_type: params[:type]).map(&:associated_resources)
    resources = resources.flatten
     hash = {}
    tag = []
    hash["Router_Inventory"] = []
    hash["Tags"] = []
      ln = @current_network
      hash["Network"] = [[ln.network_name, "network:#{ln.id}"]] if !resources.include? "network:#{ln.id}"
      current_user.router_inventories_full.where(location_network_id: ln.id).each do |ri|
        if  !resources.include? "AP:#{ri.id}"
         hash["Router_Inventory"] << ["#{ri.name.present? ? (ri.name + " (#{ri.mac_id.last(8)})") : ri.mac_id}", "AP:#{ri.id}"]
        end
      end

      current_user.router_inventories_full.where(location_network_id: ln.id).each do |ri|
        ri.tags.each do |l|
          if  !resources.include? "tag:#{ri.id}"
            tag << [l.name, "tag:#{l.id}"]
          end
        end
      end
      hash["Tags"] = tag.uniq
      resource_hash = ''
      hash.each do |h|
        resource_hash += '<optgroup label=' + h[0].to_s + '>'
        h[1].each do |v|
          if resources.include? v[1]
            resource_hash += '<option value=' + v[1].to_s + ' selected=selected>' + v[0] +'</option></optgroup>'
          else
            resource_hash += '<option value=' + v[1].to_s + '>' + v[0] +'</option></optgroup>'
          end
        end
      end
    render :json=> {:data => resource_hash}
  end

  def event_logging
    unless @current_network.blank?
      @event_logging = EventLogging.new
      @mac_ids = @current_network.router_inventories.map {|ri| ["#{ri.name.present? ? (ri.name + " (#{ri.mac_id.last(8)})") : ri.mac_id}", "#{ri.mac_id}"]}
      @event_loggings = EventLogging.where(:location_network_id => @current_network.id)
    end
  end

  def change_network
    change_user_network
  end

  def filter_event_logging
    zone_tz = @current_network.get_timezone || 'UTC'

    from_date = params[:date].to_s.split('-')[0].presence
    to_date   = params[:date].to_s.split('-')[1].presence

    s_h = from_date ? ActiveSupport::TimeZone.new(zone_tz).parse(from_date.to_s).utc : nil
    e_h = to_date ? ActiveSupport::TimeZone.new(zone_tz).parse(to_date.to_s).end_of_day.utc : nil

    query = {}
    if s_h && e_h
      query[:timestamp] = { '$gte' => s_h, '$lt' => e_h }
    elsif s_h
      query[:timestamp] = { '$gte' => s_h, '$lt' => s_h + 1.day }
    end

    query[:type_id] = { '$in' => params[:type_id].split(',').map(&:to_i) } if params[:type_id].present?
    query[:category_id] = { '$in' => params[:category].split(',').map(&:to_i) } if params[:category].present?
    query[:mac_id] = { '$in' => params[:mac].split(',') } if params[:mac].present?
    
    unless params[:org_id] == '1'
      query[:location_network_id] = @current_network.id
    end

    @network = @current_network
    @event_loggings = EventLogging.where(query).limit(1000).order(timestamp: :desc)

    respond_to do |format|
      format.json # fallback to jbuilder

      format.csv do
        headers['Content-Disposition'] = "attachment; filename=\"event_loggings_#{Time.now.to_i}.csv\""
        headers['Content-Type'] ||= 'text/csv'
        headers['X-Accel-Buffering'] = 'no'
        headers['Cache-Control'] = 'no-cache'

        self.response_body = Enumerator.new do |yielder|
          yielder << "ID,Timestamp,Type ID,Category ID,MAC ID,Description\n"

          # Stream directly from the MongoDB 
          EventLogging.collection.find(query).sort(timestamp: -1).batch_size(500).each do |doc|
            # Extract fields manually (safe from model callbacks/associations)
            row = [
              doc['_id'],
              doc['timestamp'],
              doc['type_id'],
              doc['category_id'],
              doc['mac_id'],
              doc['description']
            ].map { |v| "\"#{v}\"" }.join(',')

            yielder << row + "\n"
          end
        end
      end
    end
  end
 
  def destroy
    @logging = @current_network.loggings.find_by_id(params[:id])
    unless @logging.blank?
      if @logging.destroy
        flash[:success] = "Successfully deleted Logging details #{@logging.name}"
      else
        flash[:notice] = "Oops! there was some problem in deleting Logging details"
        Rails.logger.warn "#{@logging.errors.full_messages}"
      end
    else
       flash[:warning] = "Oops! Logging details not found"
    end
    respond_to do |format|
      format.json
      format.html { redirect_to logging_index_path }
    end
  end

  private

  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::LoggingAbility.new(current_user)
    else
      @current_ability ||= Ability.new(current_user)
    end
  end

  def logging_params
    params.require(:logging).permit(:name,:is_enabled,:logging_type,:upload_type,:location_network_id, :associated_resources => [],:extra_data => [:uploaded_user,:upload_url,:upload_password,:ip_address,:port,:username,:password])
  end

end
