<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

trait WPMR_Session_Mgt {

	/**
	 * Destroy/rotate WordPress user sessions to force logouts.
	 *
	 * This is invoked via the generic AJAX dispatcher `wpmr_ajax_request()` from the
	 * admin UI (see the `malcure_destroy_sessions` button click handler).
	 *
	 * Behavior:
	 * - For every logged-in user other than `$id`, destroys all their sessions.
	 * - For the user matching `$id`, destroys all *other* sessions while keeping the
	 *   current session token active.
	 *
	 * Note: This method does not perform capability/nonce checks itself; those are
	 * expected to be enforced by the caller/dispatcher.
	 *
	 * Better name: logout_all_other_users_sessions()
	 *
	 * @param int|string|false $id Current user ID (passed from JS). If falsy, the method returns early.
	 * @return void
	 */
	function destroy_sessions( $id = false ) {
		$users = $this->get_users_loggedin();
		if ( ! $id ) {
			return;
		}
		foreach ( $users as $user ) {
			$sessions = WP_Session_Tokens::get_instance( $user->ID );
			if ( $user->ID != $id ) {
				$sessions->destroy_all();
			} else {
				$sessions->destroy_others( wp_get_session_token() );
			}
		}
		// wp_send_json_success();
	}

	/**
	 * Shuffle (rotate) WordPress auth salts in wp-config.php.
	 *
	 * Called from the admin UI via the `wpmr_ajax_request()` dispatcher using the
	 * method name `ajax_shuffle_salts`.
	 *
	 * Side effects:
	 * - Rewrites the values of AUTH_KEY/SECURE_AUTH_KEY/LOGGED_IN_KEY/NONCE_KEY and
	 *   AUTH_SALT/SECURE_AUTH_SALT/LOGGED_IN_SALT/NONCE_SALT.
	 * - Invalidates existing auth cookies, which effectively logs users out.
	 *
	 * Return semantics:
	 * - Returns a string (often HTML wrapped in `<p>...</p>`) intended to be JSON-encoded
	 *   by `wpmr_ajax_request()` via `wp_send_json( $result )`.
	 * - This method does not call `wp_send_json_*()` directly.
	 *
	 * Better name: rotate_wp_config_auth_salts()
	 *
	 * @return string Human-readable status message (HTML string in most cases).
	 */
	function ajax_shuffle_salts() {
		WP_Filesystem();
		global $wp_filesystem;
		$config_path = $this->get_wp_config_path();
		if ( ! $config_path ) {
			return 'Failed to get location of wp-config.php';
		}
		$is_writable = $wp_filesystem->is_writable( $config_path );
		if ( ! $is_writable ) {
			return 'wp-config.php is not writable.';
		}
		$config  = $wp_filesystem->get_contents( $config_path );
		$defines = array(
			'AUTH_KEY',
			'SECURE_AUTH_KEY',
			'LOGGED_IN_KEY',
			'NONCE_KEY',
			'AUTH_SALT',
			'SECURE_AUTH_SALT',
			'LOGGED_IN_SALT',
			'NONCE_SALT',
		);
		foreach ( $defines as $define ) {
			if ( empty( $salts ) ) {
				$salts = $this->generate_salt();
			}
			$salt = array_pop( $salts );
			if ( empty( $salt ) ) {
				$salt = wp_generate_password( 64, true, true );
			}
			$salt   = str_replace( '$', '\\$', $salt );
			$regex  = "/(define\s*\(\s*(['\"])$define\\2\s*,\s*)(['\"]).+?\\3(\s*\)\s*;)/";
			$config = preg_replace( $regex, "\${1}'$salt'\${4}", $config );
		}
		if ( $wp_filesystem->put_contents( $config_path, $config ) ) {
			return '<p>Successfully shuffled WordPress salts. You\'ll need to login again to continue.</p>';
		} else {
			return '<p>Failed to write to wp-config.php.</p>';
		}
		return '<p>Failed to get wp-config.php location or it is not writable.</p>';
	}

}
