module Twitch
  class UserPolicy < ApplicationPolicy
    DATA_CLASSIFICATION_RESTRICTED = Set[
      :id, :login, :deleted_on, :terms_of_service_violation, :dmca_violation,
      :description, :email_verified, :category, :delay, :last_login,
      :created_on, :admin, :subadmin, :global_mod, :displayname,
      :tos_violation_count, :dmca_violation_count, :banned_until,
      :enable_email_reuse, :deletion_hold, :language, :username_flagged_on,
      :twofa_info
    ].freeze
    DATA_CLASSIFICATION_CUSTOMER = Set[
      :email, :location, :remote_ip, :birthday, :phone_number,
      :authy_last_four_digits, :authy_country_code, :authy_region_code
    ].merge(DATA_CLASSIFICATION_RESTRICTED).freeze

    # see ./app/concerns/attribute_read_authorized.rb for usage of this
    def permitted_read_attributes
      if user.permitted_on_twitch_user?(BeefCake::Permission.for(:users), @record)
        return DATA_CLASSIFICATION_CUSTOMER
      elsif user.permitted_on_twitch_user?('twitch_user:view_personal_information', @record)
        return DATA_CLASSIFICATION_CUSTOMER
      end

      DATA_CLASSIFICATION_RESTRICTED
    end

    # permissions on the Twitch::User object
    # most authorization checks on users should use allowed_on_user?
    def index?
      allowed?
    end

    def dump?
      user.permitted? BeefCake::Permission.for(:users_dump)
    end

    # this only authorizes whether the sidebar sections shows.
    # prefer allowed_on_user?
    def allowed?
      [
        BeefCake::Permission.for(:users),
        'twitch_user:view_details'
      ].any? { |p| user.permitted?(p) }
    end

    # permissions requiring the record for authorization
    def show?
      allowed_on_user?
    end

    def edit?
      update?
    end

    def update?
      [
        BeefCake::Permission.for(:users),
        'twitch_user:update_details'
      ].any? { |p| permitted_on_twitch_user?(p) }
    end

    def new?
      rename_allowed?
    end

    def create?
      rename_allowed?
    end

    def new_override?
      rename_allowed?
    end

    def create_override?
      rename_allowed?
    end

    def disable?
      allowed_on_user?
    end

    def rename_allowed?
      permitted_on_twitch_user? BeefCake::Permission.for(:user_rename)
    end

    def hard_delete?
      hard_delete_allowed?
    end

    def destroy?
      hard_delete_allowed?
    end

    def soft_delete?
      update?
    end

    def undelete?
      update?
    end

    def force_reset?
      update?
    end

    def change_password?
      update?
    end

    def disconnect_chat_sessions?
      update?
    end

    def delete_all_cookies?
      update?
    end

    def delete_all_authorizations?
      update?
    end

    def delete_account_connections?
      update?
    end

    def disable_twitchguard?
      update?
    end

    def compare_geo_ip?
      [
        BeefCake::Permission.for(:users),
        'twitch_user:view_personal_information'
      ].any? { |p| permitted_on_twitch_user?(p) }
    end

    def impersonate_user?
      permitted_on_twitch_user? BeefCake::Permission.for(:impersonate)
    end

    def grant_admin_roles?
      permitted_on_twitch_user? BeefCake::Permission.for(:staff_admins_global_mods)
    end

    def hard_delete_allowed?
      permitted_on_twitch_user? BeefCake::Permission.for(:hard_delete)
    end

    def manage_validated_non_partner?
      permitted_on_twitch_user? BeefCake::Permission.for(:manage_validated_non_partner)
    end

    def reset?
      update?
    end

    protected

    def permitted_on_twitch_user?(permission)
      user.permitted_on_twitch_user?(permission, @record)
    end

    def allowed_on_user?
      [
        BeefCake::Permission.for(:users),
        'twitch_user:view_details'
      ].any? { |p| permitted_on_twitch_user?(p) }
    end
  end
end
