class Ability
  include CanCan::Ability

  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
    user ||= User.new # guest user
    if user.is_admin? || user.is_super_admin || user.machine_token_user?
      #ADMIN and SUPER ADMIN User Privileges
      can :manage, Organisation, :id => user.organisation_id
      can :manage, RouterInventory, :id => user.organisation.router_inventories.pluck(:id)
      can :manage, Command, :id => user.commands.pluck(:id)
      can :manage, Upgrade, :id => Upgrade.where(organisation_id: user.organisation_id).pluck(:id)
      can :manage, LocationNetwork, :id => user.location_networks.pluck(:id)
      can :manage, SimManagement, :id => user.organisation.sim_managements.pluck(:id)
      #can :manage, PurchaseOrder, :id => user.organisation.purchase_order.pluck(:id)
      can :manage, User, :id => User.where(organisation_id: user.organisation_id).pluck(:id)
      can :manage, WiredConfig, :id => user.wired_configs.pluck(:id)
      can :manage, NetworkSsid, :id => user.network_ssids.pluck(:id)
      can :manage, Report, :id => user.reports.pluck(:id)
      can :manage, ScheduledReport
      can :manage, NtpServer, :id => user.ntp_servers.pluck(:id)
      can :manage, Alert, :id => user.alerts.pluck(:id)
      can :manage, Notification, :ap_mac_id.in => eval("user.router_inventories.pluck(:mac_id)")
      can :manage, RadioProfile, :id => user.radio_profiles.pluck(:id)
      can :manage, InitTemplate, :id => user.init_templates.pluck(:id)
      can :manage, RadiusConfiguration, :id => user.organisation.radius_configurations.pluck(:id)
      can :manage, PortforwardingGroup, :id => user.organisation.portforwarding_groups.pluck(:id)
      can :manage, AclGroup, :id => user.organisation.acl_groups.pluck(:id)
      can :manage, IntegrationType, :id => user.organisation.integration_types.pluck(:id)
      can :manage, StaticRoute, :id => user.static_routes.pluck(:id)
      # can :manage, VLan, :id => user.organisation.v_lans.pluck(:id)
      can :manage, VLan, :id => user.location_networks.map {|v| v.v_lan_ids}.flatten
      can :manage, SnmpConfig, :id => user.organisation.snmp_configs.pluck(:id)
      can :manage, Sqm, :id => user.organisation.sqms.pluck(:id)
      can :manage, AirQualityConfig, :id => user.organisation.air_quality_config.try(:id)
      can :manage, PublicActivity::Activity
      can :manage, NotificationGroup
      can :manage, FirewallConfig, :id => user.firewall_configs.pluck(:id)
      can :manage, Logging, :id => user.loggings.pluck(:id)
      can :manage, VpnConfig, :id => user.vpn_configs.pluck(:id)
      can :manage, SwitchConfiguration, :id => user.switch_configurations.pluck(:id)
      can :manage, AssumeUserDetail
      can :manage, EventLogging
    elsif user.is_network_admin?
      permissions = user.unities.pluck(:permission)
      can [:read, :update,:user_setting,:update_user_setting], User, :id => user.id
      can :report, Report
      can [:read, :list_activity], PublicActivity::Activity
      can :manage, AssumeUserDetail
      #Limited access Privileges
      if permissions.include?('limited')
        can :read, LocationNetwork, :id => user.networks_with_limited_access.pluck(:id)
        can :read, VLan, :id => user.networks_with_limited_access.map {|v| v.v_lan_ids}.flatten
        network_admin_privileges user, 'limited'
      end
      #Full access Privileges
      if permissions.include?('full')
        can [:read, :update, :destroy, :network_list], LocationNetwork, :id => user.networks_with_full_access.pluck(:id)
        can :manage, VLan, :id => user.networks_with_full_access.map {|v| v.v_lan_ids}.flatten
        can :manage, EventLogging
        network_admin_privileges user, 'full'
      end
      if user.networks_with_limited_access.any?
        network_admin_common_privileges user, 'limited'
      end
      if user.networks_with_full_access.any?
        network_admin_common_privileges user, 'full'
      end
    else
      case user.role.try(:name)
      when "monitor_only"
        can [:read, :update], User, :id => user.id
        can [:read,:event_logging], EventLogging
        can :read, Notification, :id => Notification.where(:location_network_id.in => location_networks.pluck(:id))
        can :read, RouterInventory, :id => user.router_inventories.pluck(:id)
        can [:user_setting,:update_user_setting], User, :id => user.id
      when "network_monitor"
        can [:read, :update], User, :id => user.id
        can [:read, :report, :download_pdf], Report, :id => Report.where(location_network_id: user.location_networks.pluck(:id))
        can [:read,:event_logging], EventLogging
        can :read, Notification, :id => Notification.where(:location_network_id.in => location_networks.pluck(:id))
        can :read, RouterInventory, :id => user.router_inventories.pluck(:id)
        can [:user_setting,:update_user_setting], User, :id => user.id
      when "nw_care_expert"
        can :read, User, :id => User.where(organisation_id: user.organisation_id).pluck(:id) - [user.id]
        can [:update], User, :id => user.id
        can :read, LocationNetwork, :id => user.location_networks.pluck(:id)
        can [:read, :report, :download_pdf], Report, :id => Report.where(location_network_id: user.location_networks.pluck(:id))
        can [:read,:event_logging], EventLogging
        can :read, Notification, :id => Notification.where(:location_network_id.in => user.location_networks.pluck(:id))
        can [:read, :update, :index], RouterInventory, :id => user.router_inventories.pluck(:id)
        can [:user_setting,:update_user_setting], User, :id => user.id
        can [:read, :list_activity], PublicActivity::Activity
        can :read, NetworkSsid, id: user.network_ssids.pluck(:id)
        can :read, WiredConfig, id: user.wired_configs.pluck(:id)
        can :manage, VLan, id: VLan.where(location_network_id: user.location_networks.pluck(:id))
        can :manage, SwitchConfiguration, id: user.switch_configurations.pluck(:id)
        can :manage, Upgrade, :id => Upgrade.where(organisation_id: user.organisation_id, router_inventory_id: user.router_inventories.pluck(:id)).pluck(:id)
        can :read, NtpServer, :id => user.ntp_servers.pluck(:id)
        can :read, FirewallConfig, :id => user.firewall_configs.pluck(:id)
        can :manage, RadioProfile, :id => user.radio_profiles.pluck(:id)
        can :read, Alert, :id => user.alerts.pluck(:id)
        can :read, AclGroup, :id => user.organisation.acl_groups.pluck(:id)
        can :read, SnmpConfig, :id => user.organisation.snmp_configs.pluck(:id)
        can :read, NotificationGroup, :id => user.organisation.notification_groups.pluck(:id)
        can :read, IntegrationType, :id => user.organisation.integration_types.pluck(:id)
        can :read, AssumeUserDetail
      when "nw_care_devices"
        can [:read, :update], User, :id => user.id
        can :read, LocationNetwork, :id => user.location_networks.pluck(:id)
        can [:read, :report, :download_pdf], Report, :id => Report.where(location_network_id: user.location_networks.pluck(:id))
        can [:read,:event_logging], EventLogging
        can :read, Notification, :id => Notification.where(:location_network_id.in => user.location_networks.pluck(:id))
        can [:read, :update, :index], RouterInventory, :id => user.router_inventories.pluck(:id)
        can [:user_setting,:update_user_setting], User, :id => user.id
        can [:read, :list_activity], PublicActivity::Activity
        can :read, NetworkSsid, id: user.network_ssids.pluck(:id)
        can :read, WiredConfig, id: user.wired_configs.pluck(:id)
        can :read, VLan, id: VLan.where(location_network_id: user.location_networks.pluck(:id))
        can :read, SwitchConfiguration, id: user.switch_configurations.pluck(:id)
        can :read, Upgrade, :id => Upgrade.where(organisation_id: user.organisation_id, router_inventory_id: user.router_inventories.pluck(:id)).pluck(:id)
        can :read, FirewallConfig, :id => user.firewall_configs.pluck(:id)
        can :read, RadioProfile, :id => user.radio_profiles.pluck(:id)
        can :read, Alert, :id => user.alerts.pluck(:id)
        can :read, AclGroup, :id => user.organisation.acl_groups.pluck(:id)
        can :read, SnmpConfig, :id => user.organisation.snmp_configs.pluck(:id)
        can :read, NotificationGroup, :id => user.organisation.notification_groups.pluck(:id)
        can :read, IntegrationType, :id => user.organisation.integration_types.pluck(:id)
        can :read, AssumeUserDetail
      when "nw_care_general_t1"
        can [:read, :update], User, :id => user.id
        can :read, LocationNetwork, :id => user.location_networks.pluck(:id)
        can [:read, :report, :download_pdf], Report, :id => Report.where(location_network_id: user.location_networks.pluck(:id))
        can [:read,:event_logging], EventLogging
        can :read, Notification, :id => Notification.where(:location_network_id.in => location_networks.pluck(:id))
        can [:read, :update, :index], RouterInventory, :id => user.router_inventories.pluck(:id)
        can [:user_setting,:update_user_setting], User, :id => user.id
        can [:read, :list_activity], PublicActivity::Activity
        can :read, NetworkSsid, id: user.network_ssids.pluck(:id)
        can :read, WiredConfig, id: user.wired_configs.pluck(:id)
        can :read, VLan, id: VLan.where(location_network_id: user.location_networks.pluck(:id))
        can :read, SwitchConfiguration, id: user.switch_configurations.pluck(:id)
        can :read, Upgrade, :id => Upgrade.where(organisation_id: user.organisation_id, router_inventory_id: user.router_inventories.pluck(:id)).pluck(:id)
        can :read, Alert, :id => user.alerts.pluck(:id)
      when "nw_onboarding_manager"
        can [:read, :update], User, :id => user.id
        can :read, LocationNetwork, :id => user.location_networks.pluck(:id)
        can :manage, NetworkSsid, :id => user.network_ssids.pluck(:id)
        can :manage, WiredConfig, :id => user.wired_configs.pluck(:id)
        can :manage, RouterInventory, :id => user.router_inventories.pluck(:id)
        can :manage, VLan, id: VLan.where(location_network_id: user.location_networks.pluck(:id))
        can :manage, SwitchConfiguration, id: user.switch_configurations.pluck(:id)
        can :manage, Report, :id => user.reports.pluck(:id)
        can [:read,:event_logging], EventLogging
        can :manage, Notification, :id => Notification.where(:location_network_id.in => user.location_networks.pluck(:id))
        can [:read, :list_activity], PublicActivity::Activity
        can :manage, Upgrade, :id => Upgrade.where(organisation_id: user.organisation_id, router_inventory_id: user.router_inventories.pluck(:id)).pluck(:id)
        can [:user_setting,:update_user_setting], User, :id => user.id
      when "nw_onboarding_tech_team"
        can [:read, :update], User, :id => user.id
        can :read, LocationNetwork, :id => user.location_networks.pluck(:id)
        can :manage, NetworkSsid, :id => user.network_ssids.pluck(:id)
        can :manage, WiredConfig, :id => user.wired_configs.pluck(:id)
        can :manage, RouterInventory, :id => user.router_inventories.pluck(:id)
        can :manage, VLan, id: VLan.where(location_network_id: user.location_networks.pluck(:id))
        can :manage, SwitchConfiguration, id: user.switch_configurations.pluck(:id)
        can [:read,:event_logging], EventLogging
        can :manage, Report, :id => user.reports.pluck(:id)
        can :manage, Notification, :id => Notification.where(:location_network_id.in => user.location_networks.pluck(:id))
        can [:read, :list_activity], PublicActivity::Activity
        can :manage, Upgrade, :id => Upgrade.where(organisation_id: user.organisation_id, router_inventory_id: user.router_inventories.pluck(:id)).pluck(:id)
        can :manage, NtpServer, :id => user.ntp_servers.pluck(:id)
        can :manage, Alert, :id => user.alerts.pluck(:id)
        can :manage, FirewallConfig, :id => user.firewall_configs.pluck(:id)
        can :read, AclGroup, :id => user.organisation.acl_groups.pluck(:id)
        can [:user_setting,:update_user_setting], User, :id => user.id        
      when "network_r&d"
        can [:read, :update], User, :id => user.id
        can :read, LocationNetwork, :id => user.location_networks.pluck(:id)
        can :manage, NetworkSsid, :id => user.network_ssids.pluck(:id)
        can :manage, WiredConfig, :id => user.wired_configs.pluck(:id)
        can :manage, RouterInventory, :id => user.router_inventories.pluck(:id)
        can :manage, VLan, id: VLan.where(location_network_id: user.location_networks.pluck(:id))
        can :manage, SwitchConfiguration, id: user.switch_configurations.pluck(:id)
        can :manage, Report, :id => user.reports.pluck(:id)
        can [:read,:event_logging], EventLogging
        can [:read, :list_activity], PublicActivity::Activity
        can :manage, NtpServer, :id => user.ntp_servers.pluck(:id)
        can :manage, FirewallConfig, :id => user.firewall_configs.pluck(:id)
        can :manage, Logging, :id => user.loggings.pluck(:id)
        can :manage, Upgrade, :id => Upgrade.where(organisation_id: user.organisation_id, router_inventory_id: user.router_inventories.pluck(:id)).pluck(:id)
        can [:user_setting,:update_user_setting], User, :id => user.id
        can :manage, AssumeUserDetail
      when "organization_monitor"
        can [:read, :update], User, :id => user.id
        can :read, LocationNetwork, :id => user.location_networks.pluck(:id)
        can :read, NetworkSsid, :id => user.network_ssids.pluck(:id)
        can :read, WiredConfig, :id => user.wired_configs.pluck(:id)
        can :read, RouterInventory, :id => user.router_inventories.pluck(:id)
        can [:read, :list_activity], PublicActivity::Activity
        can [:read, :report, :download_pdf], Report, :id => Report.where(location_network_id: user.location_networks.pluck(:id))
        can [:read,:event_logging], EventLogging
        can :read, Notification, :id => Notification.where(:location_network_id.in => location_networks.pluck(:id))
        can [:user_setting,:update_user_setting], User, :id => user.id
      else
        can [:read, :update], User, :id => user.id
        can :read, LocationNetwork, :id => user.location_networks.pluck(:id)
        can :read, NetworkSsid, :id => user.network_ssids.pluck(:id)
        can :read, WiredConfig, :id => user.wired_configs.pluck(:id)
        can :read, RouterInventory, :id => user.router_inventories.pluck(:id)
        can :read, PublicActivity::Activity
        can [:user_setting,:update_user_setting], User, :id => user.id
      end
    end
  end

  def network_admin_privileges user, access
    ability = access == 'full' ? :manage : :read
    can ability, WiredConfig, :id => eval("user.wired_configs_#{access}.pluck(:id)")
    can ability, NetworkSsid, :id => eval("user.network_ssids_#{access}.pluck(:id)")
    can [ability, :download_pdf], Report, :id => eval("user.reports_#{access}.pluck(:id)")
    can ability, NtpServer, :id => eval("user.ntp_servers_#{access}.pluck(:id)")
    can ability, Alert, :id => eval("user.alerts_#{access}.pluck(:id)")
    can ability, Notification, :ap_mac_id.in => eval("user.router_inventories_#{access}.pluck(:mac_id)")
    can ability, FirewallConfig, :id => eval("user.firewall_configs_#{access}.pluck(:id)")
    can ability, Logging, :id => user.loggings.pluck(:id)
    can ability, VpnConfig, :id => user.vpn_configs.pluck(:id)
  end

  def network_admin_common_privileges user, access
    ability = access == 'full' ? :manage : :read
    can ability, RouterInventory, :id => eval("user.router_inventories_#{access}.pluck(:id)")
    can ability, Upgrade, :id => eval("user.upgrades_#{access}.pluck(:id)")
    can ability, Command, :id => eval("user.commands_#{access}.pluck(:id)")
  end
end