module BeefCake
  class Permission < BeefCake::Base
    attributes :id, :name, :canonical_name, :description, :created_at, :updated_at, :roles
    validates :name, presence: true

    def self.for(key)
      {
        ad_revenue_configs: 'ad_revenue_configs',
        admin_permissions: 'admin_permissions',
        admin_image_upload: 'admin_image_upload',
        audits: 'audits',
        bits_jobs: 'bits_jobs',
        boxart: 'boxart_upload',
        broadcaster_ad_settings: 'broadcaster_ad_settings',
        chat_properties: 'chat_properties',
        dmca_takedowns: 'dmca_takedowns',
        dmca_copyright_holders: 'dmca_copyright_holders',
        communities: 'communities',
        global_banned_words: 'global_banned_words',
        gift_cards: 'gift_cards',
        history_gdpr_reports: 'history_gdpr_reports',
        history_gdpr_deletions: 'history_gdpr_deletions',
        hard_delete: 'hard_delete',
        impersonate: 'impersonate',
        reservations: 'reservations',
        manage_partner_status: 'manage_partner_status',
        manage_affiliate_status: 'manage_affiliate_status',
        manage_developer_status: 'manage_developer_status',
        manage_twitch_teams: 'manage_twitch_teams',
        notifications: 'notifications',
        oauth_clients: 'oauth2_clients',
        payout_entities: 'payout_entities',
        payout_entities_bulk_invitation_0cpm: 'payout_entities_bulk_invitation_0cpm',
        payout_entities_bulk_invitation_affiliate: 'payout_entities_bulk_invitation_affiliate',
        payout_entities_bulk_invitation_partner: 'payout_entities_bulk_invitation_partner',
        purchase_orders: 'purchase_orders',
        purchase_profiles: 'purchase_profiles',
        purchase_payments: 'purchase_payments',
        purchase_refunds: 'purchase_refunds',
        promotions: 'promotions',
        games: 'games',
        graffiti: 'graffiti',
        content_tag: 'content_tag',
        report_clips_write: 'aegis_report_clip_write',
        revenue_reporting: 'revenue_reporting',
        scheduled_vods: 'scheduled_vods',
        staff_management: 'staff_management',
        support_tools: 'support_tools',
        ticket_products: 'ticket_products',
        twitch_events: 'twitch_events',
        user_bits: 'user_bits',
        user_block: 'user_block',
        user_rename: 'user_rename',
        users: 'users',
        users_dump: 'users_dump',
        vod_appeals: 'vod_appeals',
        vods: 'vods',
        channel_properties: 'channel_properties',
        xsolla: 'xsolla',
        staff_admins_global_mods: 'staff_admins_global_mods',
        manage_validated_non_partner: 'manage_validated_non_partner',
        blocked_ips: 'blocked_ips',
        rewards: 'rewards',
        product_key_generation: 'product_key_generation',
        transactions_search: 'transactions_search',
        moderate_bits_badges: 'moderate_bits_badges',
        bits_catalog: 'bits_catalog'
      }[key] || raise("Unknown permission #{key}")
    end

    def self.all(_options = {})
      data = twirp_data(client.get_legacy_permissions(
                          Twitch::Fulton::Beefcake::GetLegacyPermissionsRequest.new
      ))

      perms = data.legacy_permissions.map do |p|
        from_attributes(
          id: p.id,
          canonical_name: p.id,
          description: p.description,
          name: p.name
        )
      end

      paginate perms
    end

    def self.find(id, _options = {})
      data = twirp_data(client.get_legacy_permission(
                          Twitch::Fulton::Beefcake::GetLegacyPermissionRequest.new(id: id)
      ))

      res = from_attributes(
        id: data.id,
        canonical_name: data.id,
        description: data.description,
        name: data.name,
        roles: data.roles.map do |r|
          Role.from_attributes(id: r.id, name: r.name)
        end
      )
      res
    end

    def save
      return false unless valid?

      if persisted?
        handle_error(client.update_legacy_permission(
                       Twitch::Fulton::Beefcake::UpdateLegacyPermissionRequest.new(
                         id: id,
                         name: Google::Protobuf::StringValue.new(value: name),
                         description: Google::Protobuf::StringValue.new(value: description)
                       )
        ))
      else
        handle_error(client.create_legacy_permission(Twitch::Fulton::Beefcake::CreateLegacyPermissionRequest.new(
                                                       id: canonical_name,
                                                       name: name,
                                                       description: description
        )))
      end
      true
    end

    def destroy
      handle_error(
        client.delete_legacy_permission(
          Twitch::Fulton::Beefcake::DeleteLegacyPermissionRequest.new(id: id)
        )
      )
      true
    end

    def roles
      @roles.to_a
    end

    def roles_ids
      roles.map &:id
    end

    def role_ids=(ids = [])
      self.roles = ids.map do |role_id|
        Role.new(id: role_id)
      end
    end
  end
end
