<?php
/**
 * Register rest api routes.
 *
 * @package {{phpClassName}}
 */

namespace {{phpClassName}};

/**
 * Register custom rest API endpoints.
 *
 * @since {{version}}
 */
class RegisterRestApi {

	/**
	 * The plugin instance.
	 *
	 * @var array
	 */
	private $plugin_instance;

	/**
	 * Register class with appropriate WordPress hooks.
	 *
	 * @since {{version}}
	 * @return void
	 */
	public static function register() {
		$instance = new self();
		{{#registerPlugins}}
		add_action( 'rest_api_init', array( $instance, 'register_routes' ) );
		{{/registerPlugins}}
		{{#registerFilters}}
		add_filter( 'rest_pre_dispatch', array( $instance, 'rest_pre_dispatch' ), 10, 3 );
		{{/registerFilters}}
	}
	{{#registerFilters}}

	/**
	 * Fix REST API issue with blocks registered via PHP register_block_type to add custom attributes.
	 * Shoutout to @phpbits ( Jeffrey Carandang ) for solving this in Editorskit.
	 *
	 * @param mixed  $result  Response to replace the requested version with.
	 * @param object $server  Server instance.
	 * @param object $request Request used to generate the response.
	 *
	 * @return array Returns updated results.
	 */
	public function rest_pre_dispatch( $result, $server, $request ) {

		if ( strpos( $request->get_route(), '/wp/v2/block-renderer' ) !== false ) {

			if ( isset( $request['attributes'] ) && isset( $request['attributes']['padding'] ) ) {

				$attributes = $request['attributes'];
				unset( $attributes['padding'] );
				$request['attributes'] = $attributes;
			}
		}

		return $result;
	}
	{{/registerFilters}}
  {{#registerPlugins}}

	/**
	 * Construct the class.
	 *
	 * @since {{version}}
	 * @return void
	 */
	public function __construct() {
		$this->plugin_instance = Plugin::get_instance();
	}

	/**
	 * Register custom API routes.
	 *
	 * @return void
	 */
	public function register_routes() {

		// Shortcuts for variables.
		$plugin_instance = $this->plugin_instance;
		$slug            = $plugin_instance->slug;

		// Register get_options route.
		// As of WordPress 5.5 permission_callback is required:
		// https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/#permissions-callback.
		register_rest_route(
			"$slug/v1",
			'/settings/',
			array(
				'methods'             => \WP_REST_Server::READABLE,
				'callback'            => array( $this, 'get_settings' ),
				'permission_callback' => function () {
					return current_user_can('edit_others_posts');
				},
			)
		);

		// Register update_options route.
		// Path variable is passed on to callback along with data.
		// We can define any path variable.
		// As of WordPress 5.5 permission_callback is required:
		// https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/#permissions-callback.
		// Review api here: http://localhost:{{port}}/wp-json/{{slug}}/v1/settings/.
		register_rest_route(
			"$slug/v1",
			'/settings/(?P<setting_name>[a-zA-Z0-9-_]+)',
			array(
				'methods'             => \WP_REST_Server::EDITABLE,
				'callback'            => array( $this, 'update_settings' ),
				'permission_callback' => function () {
					return current_user_can('edit_others_posts');
				},
			)
		);
		{{#softwareLicensing}}
		// Register update_options route.
		// Path variable is passed on to callback along with data.
		// We can define any path variable.
		// As of WordPress 5.5 permission_callback is required:
		// https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/#permissions-callback.
		// Review api here: http://localhost:8888/wp-json/font/v1/settings/.
		register_rest_route(
			UTILITY_SLUG . '/v1',
			'/edd-sl/(?P<action_name>[a-zA-Z0-9-_]+)',
			array(
				'methods'             => \WP_REST_Server::EDITABLE,
				'callback'            => array(
					$this,
					'update_software_licensing',
				),
				'permission_callback' => function () {
					return current_user_can( 'edit_others_posts' );
				},
			)
		);
		{{/softwareLicensing}}
	}

	/**
	 * Callback for GET /options/ route.
	 *
	 * @return $response
	 */
	public function get_settings() {

		// Shortcuts for variables.
		$plugin_instance = $this->plugin_instance;
		$slug_snake_case = $plugin_instance->slug_snake_case;
		$settings        = get_option( $slug_snake_case . '_settings' );

		$response = new \WP_REST_Response( $settings, 200 );

		return $response;
	}

	/**
	 * Callback for POST /settings/ route.
	 *
	 * @param mixed[] $request Array of settings.
	 * @return $response
	 */
	public function update_settings( $request ) {

		// Shortcuts for variables.
		$plugin_instance = $this->plugin_instance;
		$slug_snake_case = $plugin_instance->slug_snake_case;

		// Grab the setting from the path variable setting_name.
		$setting = $request['setting_name'];

		// Since we are passing a JSON string, we can use the
		// get_json_params() method to retrieve the parameters.
		// This also allows us to grab the setting value we need to update.
		$request_body = $request->get_json_params();

		// Since our settings are stored in a multi-dimensional array
		// we need to grab the entire array and update the setting
		// corresponding with the request we received.
		$settings = get_option( $slug_snake_case . '_settings' );

		// Update the setting that corresponds with the request.
		$settings[ $setting ] = $request_body[ $setting ];

		// Update the entire settings array with the updated settings.
		update_option( $slug_snake_case . '_settings', $settings );

		// If we need the data in the response, pass it back here,
		// otherwise we're just passing back true and a 201 server code.
		$response_code    = wp_remote_retrieve_response_code( $request );
		$response_message = wp_remote_retrieve_response_message( $request );
		$response         = new \WP_REST_Response(
			array(
				'status'        => $response_code,
				'response'      => $response_message,
				'body_response' => $request_body,
			)
		);

		return $response;
	}
	{{#softwareLicensing}}

	/**
	 * Callback for POST /settings/ route.
	 *
	 * @param mixed[] $request Array of settings.
	 * @return $response
	 */
	public function update_software_licensing( $request ) {

		// Grab the action from the path variable action_name.
		$action = $request['action_name'];

		// Since we are passing a JSON string, we can use the
		// get_json_params() method to retrieve the parameters.
		// This also allows us to grab the setting value we need to update.
		$request_data = $request->get_json_params();

		// Since our settings are stored in a multi-dimensional array
		// we need to grab the entire array and update the setting
		// corresponding with the request we received.
		$settings           = get_option( UTILITY_SLUG_CAMEL_CASE . 'Settings' );
		$license_key        = $request_data['licenseKey'];
		$software_licensing = SoftwareLicensing::instance();

		if ( 'activate' === $action ) {
			$license_status            = $software_licensing->activate( $license_key );
			$settings['licenseStatus'] = $license_status;
			$settings['licenseKey']    = $license_key;
		}

		if ( 'deactivate' === $action ) {
			$license_status            = $software_licensing->deactivate( $license_key );
			$settings['licenseStatus'] = $license_status;
			$settings['licenseKey']    = $license_key;
		}

		// Update the entire settings array with the updated settings.
		update_option( UTILITY_SLUG_CAMEL_CASE . 'Settings', $settings );

		// If we need the data in the response, pass it back here,
		// otherwise we're just passing back true and a 201 server code.
		$response_code    = wp_remote_retrieve_response_code( $request );
		$response_message = wp_remote_retrieve_response_message( $request );
		$response         = new \WP_REST_Response(
			array(
				'status'        => $response_code,
				'response'      => $response_message,
				'body_response' => $request_body,
				'settings'      => $settings,
			)
		);

		return $response;
	}
	{{/softwareLicensing}}
	{{/registerPlugins}}
}
