<?php

namespace JNews\Paywall\Gateways\Stripe\Lib\Api_Operations;

use JNews\Paywall\Gateways\Stripe\Lib\Util\Util;

/**
 * Trait for resources that have nested resources.
 *
 * This trait should only be applied to classes that derive from StripeObject.
 */
trait Nested_Resource {

	/**
	 * @param string            $method
	 * @param string            $url
	 * @param array|null        $params
	 * @param array|string|null $options
	 *
	 * @return \Stripe\Lib\Stripe_Object
	 */
	protected static function _nestedResourceOperation( $method, $url, $params = null, $options = null ) {
		self::_validateParams( $params );

		list($response, $opts) = static::_staticRequest( $method, $url, $params, $options );
		$obj                   = Util::convertToStripeObject( $response->json, $opts );
		$obj->setLastResponse( $response );
		return $obj;
	}

	/**
	 * @param string      $id
	 * @param string      $nestedPath
	 * @param string|null $nestedId
	 *
	 * @return string
	 */
	protected static function _nestedResourceUrl( $id, $nestedPath, $nestedId = null ) {
		$url = static::resourceUrl( $id ) . $nestedPath;
		if ( $nestedId !== null ) {
			$url .= "/$nestedId";
		}
		return $url;
	}

	/**
	 * @param string            $id
	 * @param string            $nestedPath
	 * @param array|null        $params
	 * @param array|string|null $options
	 *
	 * @throws \Stripe\Exception\Api_Error_Exception if the request fails
	 *
	 * @return \Stripe\Stripe_Object
	 */
	protected static function _createNestedResource( $id, $nestedPath, $params = null, $options = null ) {
		$url = static::_nestedResourceUrl( $id, $nestedPath );
		return self::_nestedResourceOperation( 'post', $url, $params, $options );
	}

	/**
	 * @param string            $id
	 * @param string            $nestedPath
	 * @param string|null       $nestedId
	 * @param array|null        $params
	 * @param array|string|null $options
	 *
	 * @throws \Stripe\Exception\Api_Error_Exception if the request fails
	 *
	 * @return \Stripe\Stripe_Object
	 */
	protected static function _retrieveNestedResource( $id, $nestedPath, $nestedId, $params = null, $options = null ) {
		 $url = static::_nestedResourceUrl( $id, $nestedPath, $nestedId );
		return self::_nestedResourceOperation( 'get', $url, $params, $options );
	}

	/**
	 * @param string            $id
	 * @param string            $nestedPath
	 * @param string|null       $nestedId
	 * @param array|null        $params
	 * @param array|string|null $options
	 *
	 * @throws \Stripe\Exception\Api_Error_Exception if the request fails
	 *
	 * @return \Stripe\Stripe_Object
	 */
	protected static function _updateNestedResource( $id, $nestedPath, $nestedId, $params = null, $options = null ) {
		$url = static::_nestedResourceUrl( $id, $nestedPath, $nestedId );
		return self::_nestedResourceOperation( 'post', $url, $params, $options );
	}

	/**
	 * @param string            $id
	 * @param string            $nestedPath
	 * @param string|null       $nestedId
	 * @param array|null        $params
	 * @param array|string|null $options
	 *
	 * @throws \Stripe\Exception\Api_Error_Exception if the request fails
	 *
	 * @return \Stripe\Stripe_Object
	 */
	protected static function _deleteNestedResource( $id, $nestedPath, $nestedId, $params = null, $options = null ) {
		$url = static::_nestedResourceUrl( $id, $nestedPath, $nestedId );
		return self::_nestedResourceOperation( 'delete', $url, $params, $options );
	}

	/**
	 * @param string            $id
	 * @param string            $nestedPath
	 * @param array|null        $params
	 * @param array|string|null $options
	 *
	 * @throws \Stripe\Exception\Api_Error_Exception if the request fails
	 *
	 * @return \Stripe\Stripe_Object
	 */
	protected static function _allNestedResources( $id, $nestedPath, $params = null, $options = null ) {
		$url = static::_nestedResourceUrl( $id, $nestedPath );
		return self::_nestedResourceOperation( 'get', $url, $params, $options );
	}
}
