<?php
/**
 * Capabilities.
 *
 * @package Nisje
 */

namespace Dekode\Nisje\Resets;

/**
 * Setup login details.
 */
function caps() {
	add_filter( 'map_meta_cap', __NAMESPACE__ . '\enforce_bp_moderate_cap_for_intranet_admins', 10, 4 );
	add_filter( 'map_meta_cap', __NAMESPACE__ . '\allow_editors_to_create_users', 10, 4 );
	add_filter( 'nisje_override_rest_permission_check', __NAMESPACE__ . '\allow_super_user', 10, 3 );
}
add_action( 'init', __NAMESPACE__ . '\caps' );

/**
 * Filters a user's capabilities.
 *
 * @param array  $caps    Returns the user's actual capabilities.
 * @param string $cap     Capability name.
 * @param int    $user_id The user ID.
 * @param array  $args    Adds the context to the cap. Typically the object ID.
 */
function enforce_bp_moderate_cap_for_intranet_admins( $caps = [], $cap = '', $user_id = 0, $args = [] ) {
	// Bail if not checking the 'bp_moderate' cap.
	if ( 'bp_moderate' !== $cap ) {
		return $caps;
	}

	// Never trust inactive users.
	if ( bp_is_user_inactive( $user_id ) ) {
		return $caps;
	}

	// Only users that can 'manage_options' on this site can 'bp_moderate'.
	return [ 'nisje_administrator' ];
}

/**
 * If someone is trying to edit or delete and admin and that user isn't an admin, don't allow it
 *
 * @param array  $caps    Returns the user's actual capabilities.
 * @param string $cap     Capability name.
 * @param int    $user_id The user ID.
 * @param array  $args    Adds the context to the cap. Typically the object ID.
 */
function allow_editors_to_create_users( $caps, $cap, $user_id, $args ) {
	switch ( $cap ) {
		case 'edit_user':
		case 'remove_user':
		case 'promote_user':
			if ( isset( $args[0] ) && $args[0] === $user_id ) {
				break;
			} elseif ( ! isset( $args[0] ) || ! $args[0] ) {
				$caps[] = 'do_not_allow';
			}

			$other = new \WP_User( absint( $args[0] ) );
			if ( $other->has_cap( 'administrator' ) ) {
				if ( ! current_user_can( 'administrator' ) ) {
					$caps[] = 'do_not_allow';
				}
			}

			break;

		case 'delete_user':
		case 'delete_users':
			if ( ! isset( $args[0] ) ) {
				break;
			}

			$other = new \WP_User( absint( $args[0] ) );
			if ( $other->has_cap( 'administrator' ) ) {
				if ( ! current_user_can( 'administrator' ) ) {
					$caps[] = 'do_not_allow';
				}
			}

			break;
	}
	return $caps;
}

/**
 * Let super user through.
 *
 * @param string          $endpoint Endpoint to validate against.
 * @param string          $route    Endpoint route.
 * @param WP_REST_Request $request  Full data about the request.
 *
 * @return boolean True or false.
 */
function allow_super_user( $endpoint, $route, $request ) {
	if ( is_user_logged_in() && current_user_can( 'nisje_super_administrator' ) ) {
		return true;
	}

	return false;
}
