
#ifdef HAVE_CONFIG_H
#include "../../../ext_config.h"
#endif

#include <php.h>
#include "../../../php_ext.h"
#include "../../../ext.h"

#include <Zend/zend_operators.h>
#include <Zend/zend_exceptions.h>
#include <Zend/zend_interfaces.h>

#include "kernel/main.h"
#include "kernel/memory.h"
#include "kernel/object.h"
#include "kernel/fcall.h"
#include "kernel/operators.h"
#include "kernel/array.h"
#include "kernel/exception.h"


/**
 * This file is part of the Phalcon Framework.
 *
 * (c) Phalcon Team <team@phalcon.io>
 *
 * For the full copyright and license information, please view the
 * LICENSE.txt file that was distributed with this source code.
 */
/**
 * This class is a bag to manage the cookies.
 *
 * A cookies bag is automatically registered as part of the 'response' service
 * in the DI. By default, cookies are automatically encrypted before being sent
 * to the client and are decrypted when retrieved from the user. To set sign key
 * used to generate a message authentication code use
 * `Phalcon\Http\Response\Cookies::setSignKey()`.
 *
 * ```php
 * use Phalcon\Di\Di;
 * use Phalcon\Encryption\Crypt;
 * use Phalcon\Http\Response\Cookies;
 *
 * $di = new Di();
 *
 * $di->set(
 *     'crypt',
 *     function () {
 *         $crypt = new Crypt();
 *
 *         // The `$key' should have been previously generated in a
 *         // cryptographically safe way.
 *         $key =
 *         "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
 *
 *         $crypt->setKey($key);
 *
 *         return $crypt;
 *     }
 * );
 *
 * $di->set(
 *     'cookies',
 *     function () {
 *         $cookies = new Cookies();
 *
 *         // The `$key' MUST be at least 32 characters long and generated
 *         // using a cryptographically secure pseudo random generator.
 *         $key =
 *         "#1dj8$=dp?.ak//j1V$~%*0XaK\xb1\x8d\xa9\x98\x054t7w!z%C*F-Jk\x98\x05\\\x5c";
 *
 *         $cookies->setSignKey($key);
 *
 *         return $cookies;
 *     }
 * );
 * ```
 *
 * @phpstan-import-type http_cookie_bag from HttpTypes
 * @phpstan-import-type http_cookie_options from HttpTypes
 */
ZEPHIR_INIT_CLASS(Phalcon_Http_Response_Cookies)
{
	ZEPHIR_REGISTER_CLASS_EX(Phalcon\\Http\\Response, Cookies, phalcon, http_response_cookies, phalcon_di_abstractinjectionaware_ce, phalcon_http_response_cookies_method_entry, 0);

	/**
	 * @phpstan-var http_cookie_bag
	 */
	{
		zval _zc0;
		array_init_size(&_zc0, 1);
		zephir_declare_typed_property(phalcon_http_response_cookies_ce, SL("cookies"), &_zc0, ZEND_ACC_PROTECTED, MAY_BE_ARRAY, NULL, 0);
	}

	{
		zval _zc0;
		ZVAL_BOOL(&_zc0, 0);
		zephir_declare_typed_property(phalcon_http_response_cookies_ce, SL("isRegistered"), &_zc0, ZEND_ACC_PROTECTED, MAY_BE_BOOL, NULL, 0);
	}

	{
		zval _zc0;
		ZVAL_BOOL(&_zc0, 0);
		zephir_declare_typed_property(phalcon_http_response_cookies_ce, SL("isSent"), &_zc0, ZEND_ACC_PROTECTED, MAY_BE_BOOL, NULL, 0);
	}

	/**
	 * The cookie's sign key.
	 */
	{
		zval _zc0;
		ZVAL_NULL(&_zc0);
		zephir_declare_typed_property(phalcon_http_response_cookies_ce, SL("signKey"), &_zc0, ZEND_ACC_PROTECTED, MAY_BE_STRING|MAY_BE_NULL, NULL, 0);
	}

	{
		zval _zc0;
		ZVAL_BOOL(&_zc0, 0);
		zephir_declare_typed_property(phalcon_http_response_cookies_ce, SL("useEncryption"), &_zc0, ZEND_ACC_PROTECTED, MAY_BE_BOOL, NULL, 0);
	}

	zend_class_implements(phalcon_http_response_cookies_ce, 1, phalcon_http_response_cookiesinterface_ce);
	return SUCCESS;
}

/**
 * Constructor
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, __construct)
{
	zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
	zend_long ZEPHIR_LAST_CALL_STATUS;
	zend_string *signKey = NULL;
	zval *useEncryption_param = NULL, signKey_zv, __$true, __$false;
	zend_bool useEncryption;
	zval *this_ptr = getThis();

	ZVAL_UNDEF(&signKey_zv);
	ZVAL_BOOL(&__$true, 1);
	ZVAL_BOOL(&__$false, 0);
	static zend_string *_zephir_prop_0 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("useEncryption", 13, 1);
	}

	bool is_null_true = 1;
	ZEND_PARSE_PARAMETERS_START(0, 2)
		Z_PARAM_OPTIONAL
		Z_PARAM_BOOL(useEncryption)
		Z_PARAM_STR_OR_NULL(signKey)
	ZEND_PARSE_PARAMETERS_END();
	ZEPHIR_METHOD_GLOBALS_PTR = pecalloc(1, sizeof(zephir_method_globals), 0);
	zephir_memory_grow_stack(ZEPHIR_METHOD_GLOBALS_PTR, __func__);
	if (ZEND_NUM_ARGS() > 0) {
		useEncryption_param = ZEND_CALL_ARG(execute_data, 1);
	}
	if (!useEncryption_param) {
		useEncryption = 1;
	} else {
		}
	if (!signKey) {
		ZEPHIR_INIT_VAR(&signKey_zv);
	} else {
		zephir_memory_observe(&signKey_zv);
	ZVAL_STR_COPY(&signKey_zv, signKey);
	}
	if (useEncryption) {
		zephir_update_property_zval_cached(this_ptr, _zephir_prop_0, 911, &__$true);
	} else {
		zephir_update_property_zval_cached(this_ptr, _zephir_prop_0, 911, &__$false);
	}
	ZEPHIR_CALL_METHOD(NULL, this_ptr, "setsignkey", NULL, 0, &signKey_zv);
	zephir_check_call_status();
	ZEPHIR_MM_RESTORE();
}

/**
 * Deletes a cookie by its name
 * This method does not remove cookies from the _COOKIE super-global
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, delete)
{
	zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
	zend_long ZEPHIR_LAST_CALL_STATUS;
	zval name_zv, _COOKIE, cookie, _0, _1$$3, _2$$5;
	zend_string *name = NULL;
	zval *this_ptr = getThis();

	ZVAL_UNDEF(&name_zv);
	ZVAL_UNDEF(&_COOKIE);
	ZVAL_UNDEF(&cookie);
	ZVAL_UNDEF(&_0);
	ZVAL_UNDEF(&_1$$3);
	ZVAL_UNDEF(&_2$$5);
	static zend_string *_zephir_prop_0 = NULL;
	static zend_string *_zephir_prop_1 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("cookies", 7, 1);
	}
	if (UNEXPECTED(!_zephir_prop_1)) {
		_zephir_prop_1 = zend_string_init("container", 9, 1);
	}

	ZEND_PARSE_PARAMETERS_START(1, 1)
		Z_PARAM_STR(name)
	ZEND_PARSE_PARAMETERS_END();
	ZEPHIR_METHOD_GLOBALS_PTR = pecalloc(1, sizeof(zephir_method_globals), 0);
	zephir_memory_grow_stack(ZEPHIR_METHOD_GLOBALS_PTR, __func__);
	zephir_get_global(&_COOKIE, SL("_COOKIE"));
	zephir_memory_observe(&name_zv);
	ZVAL_STR_COPY(&name_zv, name);
	zephir_memory_observe(&cookie);
	zephir_read_property_cached(&_0, this_ptr, _zephir_prop_0, 912, PH_NOISY_CC | PH_READONLY);
	if (!(zephir_array_isset_fetch(&cookie, &_0, &name_zv, 0))) {
		if (!(zephir_array_isset_value(&_COOKIE, &name_zv))) {
			RETURN_MM_BOOL(0);
		}
		ZEPHIR_INIT_NVAR(&cookie);
		object_init_ex(&cookie, phalcon_http_cookie_ce);
		ZEPHIR_CALL_METHOD(NULL, &cookie, "__construct", NULL, 0, &name_zv);
		zephir_check_call_status();
		zephir_read_property_cached(&_1$$3, this_ptr, _zephir_prop_1, 913, PH_NOISY_CC | PH_READONLY);
		if (Z_TYPE_P(&_1$$3) != IS_NULL) {
			zephir_read_property_cached(&_2$$5, this_ptr, _zephir_prop_1, 913, PH_NOISY_CC | PH_READONLY);
			ZEPHIR_CALL_METHOD(NULL, &cookie, "setdi", NULL, 0, &_2$$5);
			zephir_check_call_status();
		}
	}
	ZEPHIR_CALL_METHOD(NULL, &cookie, "delete", NULL, 0);
	zephir_check_call_status();
	RETURN_MM_BOOL(1);
}

/**
 * Gets a cookie from the bag
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, get)
{
	zval _2;
	zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
	zend_long ZEPHIR_LAST_CALL_STATUS;
	zval name_zv, container, encryption, cookie, _0, _1, _3, _4$$4;
	zend_string *name = NULL;
	zval *this_ptr = getThis();

	ZVAL_UNDEF(&name_zv);
	ZVAL_UNDEF(&container);
	ZVAL_UNDEF(&encryption);
	ZVAL_UNDEF(&cookie);
	ZVAL_UNDEF(&_0);
	ZVAL_UNDEF(&_1);
	ZVAL_UNDEF(&_3);
	ZVAL_UNDEF(&_4$$4);
	ZVAL_UNDEF(&_2);
	static zend_string *_zephir_prop_0 = NULL;
	static zend_string *_zephir_prop_1 = NULL;
	static zend_string *_zephir_prop_2 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("cookies", 7, 1);
	}
	if (UNEXPECTED(!_zephir_prop_1)) {
		_zephir_prop_1 = zend_string_init("useEncryption", 13, 1);
	}
	if (UNEXPECTED(!_zephir_prop_2)) {
		_zephir_prop_2 = zend_string_init("signKey", 7, 1);
	}

	ZEND_PARSE_PARAMETERS_START(1, 1)
		Z_PARAM_STR(name)
	ZEND_PARSE_PARAMETERS_END();
	ZEPHIR_METHOD_GLOBALS_PTR = pecalloc(1, sizeof(zephir_method_globals), 0);
	zephir_memory_grow_stack(ZEPHIR_METHOD_GLOBALS_PTR, __func__);
	zephir_memory_observe(&name_zv);
	ZVAL_STR_COPY(&name_zv, name);
	zephir_memory_observe(&cookie);
	zephir_read_property_cached(&_0, this_ptr, _zephir_prop_0, 912, PH_NOISY_CC | PH_READONLY);
	if (zephir_array_isset_fetch(&cookie, &_0, &name_zv, 0)) {
		RETURN_CCTOR(&cookie);
	}
	ZEPHIR_CALL_METHOD(&container, this_ptr, "checkgetcontainer", NULL, 0);
	zephir_check_call_status();
	ZEPHIR_INIT_VAR(&_2);
	zephir_create_array(&_2, 1, 0);
	zephir_array_fast_append(&_2, &name_zv);
	ZEPHIR_INIT_VAR(&_3);
	ZVAL_STRING(&_3, "Phalcon\\Http\\Cookie");
	ZEPHIR_CALL_METHOD(&_1, &container, "get", NULL, 0, &_3, &_2);
	zephir_check_call_status();
	ZEPHIR_CPY_WRT(&cookie, &_1);
	ZEPHIR_CALL_METHOD(NULL, &cookie, "setdi", NULL, 0, &container);
	zephir_check_call_status();
	zephir_memory_observe(&encryption);
	zephir_read_property_cached(&encryption, this_ptr, _zephir_prop_1, 911, PH_NOISY_CC);
	if (zephir_is_true(&encryption)) {
		ZEPHIR_CALL_METHOD(NULL, &cookie, "useencryption", NULL, 0, &encryption);
		zephir_check_call_status();
		zephir_read_property_cached(&_4$$4, this_ptr, _zephir_prop_2, 914, PH_NOISY_CC | PH_READONLY);
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setsignkey", NULL, 0, &_4$$4);
		zephir_check_call_status();
	}
	RETURN_CCTOR(&cookie);
}

/**
 * Gets all cookies from the bag
 *
 * @phpstan-return http_cookie_bag
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, getCookies)
{

	RETURN_MEMBER_TYPED(getThis(), "cookies", IS_ARRAY);
}

/**
 * Check if a cookie is defined in the bag or exists in the _COOKIE
 * super-global
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, has)
{
	zend_bool _1;
	zval name_zv, _COOKIE, _0;
	zend_string *name = NULL;
	zval *this_ptr = getThis();

	ZVAL_UNDEF(&name_zv);
	ZVAL_UNDEF(&_COOKIE);
	ZVAL_UNDEF(&_0);
	static zend_string *_zephir_prop_0 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("cookies", 7, 1);
	}

	ZEND_PARSE_PARAMETERS_START(1, 1)
		Z_PARAM_STR(name)
	ZEND_PARSE_PARAMETERS_END();
	zephir_get_global(&_COOKIE, SL("_COOKIE"));
	ZVAL_STR(&name_zv, name);
	zephir_read_property_cached(&_0, this_ptr, _zephir_prop_0, 912, PH_NOISY_CC | PH_READONLY);
	_1 = zephir_array_isset_value(&_0, &name_zv);
	if (!(_1)) {
		_1 = zephir_array_isset_value(&_COOKIE, &name_zv);
	}
	RETURN_BOOL(_1);
}

/**
 * Returns if the headers have already been sent
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, isSent)
{

	RETURN_MEMBER(getThis(), "isSent");
}

/**
 * Reset set cookies
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, reset)
{
	zval _0;
	zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
	zval *this_ptr = getThis();

	ZVAL_UNDEF(&_0);
	static zend_string *_zephir_prop_0 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("cookies", 7, 1);
	}
	ZEPHIR_METHOD_GLOBALS_PTR = pecalloc(1, sizeof(zephir_method_globals), 0);
	zephir_memory_grow_stack(ZEPHIR_METHOD_GLOBALS_PTR, __func__);

	ZEPHIR_INIT_VAR(&_0);
	array_init(&_0);
	zephir_update_property_zval_cached(this_ptr, _zephir_prop_0, 912, &_0);
	RETURN_THIS();
}

/**
 * Sends the cookies to the client
 * Cookies aren't sent if headers are sent in the current request
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, send)
{
	zend_bool _1, _6;
	zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
	zval __$true, __$false, cookie, _0, _2, _3, *_4, _5;
	zend_long ZEPHIR_LAST_CALL_STATUS;
	zval *this_ptr = getThis();

	ZVAL_BOOL(&__$true, 1);
	ZVAL_BOOL(&__$false, 0);
	ZVAL_UNDEF(&cookie);
	ZVAL_UNDEF(&_0);
	ZVAL_UNDEF(&_2);
	ZVAL_UNDEF(&_3);
	ZVAL_UNDEF(&_5);
	static zend_string *_zephir_prop_0 = NULL;
	static zend_string *_zephir_prop_1 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("cookies", 7, 1);
	}
	if (UNEXPECTED(!_zephir_prop_1)) {
		_zephir_prop_1 = zend_string_init("isSent", 6, 1);
	}
	ZEPHIR_METHOD_GLOBALS_PTR = pecalloc(1, sizeof(zephir_method_globals), 0);
	zephir_memory_grow_stack(ZEPHIR_METHOD_GLOBALS_PTR, __func__);

	ZEPHIR_CALL_FUNCTION(&_0, "headers_sent", NULL, 225);
	zephir_check_call_status();
	_1 = ZEPHIR_IS_TRUE_IDENTICAL(&_0);
	if (!(_1)) {
		ZEPHIR_CALL_METHOD(&_2, this_ptr, "issent", NULL, 0);
		zephir_check_call_status();
		_1 = ZEPHIR_IS_TRUE_IDENTICAL(&_2);
	}
	if (_1) {
		RETURN_MM_BOOL(0);
	}
	zephir_read_property_cached(&_3, this_ptr, _zephir_prop_0, 912, PH_NOISY_CC | PH_READONLY);
	zephir_is_iterable(&_3, 0, "phalcon/Http/Response/Cookies.zep", 226);
	if (Z_TYPE_P(&_3) == IS_ARRAY) {
		ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(&_3), _4)
		{
			ZEPHIR_INIT_NVAR(&cookie);
			ZVAL_COPY(&cookie, _4);
			ZEPHIR_CALL_METHOD(NULL, &cookie, "send", NULL, 0);
			zephir_check_call_status();
		} ZEND_HASH_FOREACH_END();
	} else {
		ZEPHIR_CALL_METHOD(NULL, &_3, "rewind", NULL, 0);
		zephir_check_call_status();
		_6 = 1;
		while (1) {
			if (_6) {
				_6 = 0;
			} else {
				ZEPHIR_CALL_METHOD(NULL, &_3, "next", NULL, 0);
				zephir_check_call_status();
			}
			ZEPHIR_CALL_METHOD(&_5, &_3, "valid", NULL, 0);
			zephir_check_call_status();
			if (!zend_is_true(&_5)) {
				break;
			}
			ZEPHIR_CALL_METHOD(&cookie, &_3, "current", NULL, 0);
			zephir_check_call_status();
				ZEPHIR_CALL_METHOD(NULL, &cookie, "send", NULL, 0);
				zephir_check_call_status();
		}
	}
	ZEPHIR_INIT_NVAR(&cookie);
	if (1) {
		zephir_update_property_zval_cached(this_ptr, _zephir_prop_1, 915, &__$true);
	} else {
		zephir_update_property_zval_cached(this_ptr, _zephir_prop_1, 915, &__$false);
	}
	RETURN_MM_BOOL(1);
}

/**
 * Sets a cookie to be sent at the end of the request.
 *
 * This method overrides any cookie set before with the same name.
 *
 * ```php
 * use Phalcon\Http\Response\Cookies;
 *
 * $now = new DateTimeImmutable();
 * $tomorrow = $now->modify('tomorrow');
 *
 * $cookies = new Cookies();
 * $cookies->set(
 *     'remember-me',
 *     json_encode(['user_id' => 1]),
 *     (int) $tomorrow->format('U'),
 * );
 * ```
 *
 * @phpstan-param http_cookie_options $options
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, set)
{
	zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
	zval options, _3$$3;
	zend_bool secure, httpOnly;
	zend_long expire, ZEPHIR_LAST_CALL_STATUS;
	zval name_zv, *value = NULL, value_sub, *expire_param = NULL, path_zv, *secure_param = NULL, domain_zv, *httpOnly_param = NULL, *options_param = NULL, __$true, __$false, __$null, cookie, encryption, container, response, _0, _10, _1$$3, _2$$3, _4$$3, _5$$3, _6$$4, _7$$5, _8$$5, _9$$5, _11$$6;
	zend_string *name = NULL, *path = NULL, *domain = NULL;
	zval *this_ptr = getThis();

	ZVAL_UNDEF(&name_zv);
	ZVAL_UNDEF(&value_sub);
	ZVAL_UNDEF(&path_zv);
	ZVAL_UNDEF(&domain_zv);
	ZVAL_BOOL(&__$true, 1);
	ZVAL_BOOL(&__$false, 0);
	ZVAL_NULL(&__$null);
	ZVAL_UNDEF(&cookie);
	ZVAL_UNDEF(&encryption);
	ZVAL_UNDEF(&container);
	ZVAL_UNDEF(&response);
	ZVAL_UNDEF(&_0);
	ZVAL_UNDEF(&_10);
	ZVAL_UNDEF(&_1$$3);
	ZVAL_UNDEF(&_2$$3);
	ZVAL_UNDEF(&_4$$3);
	ZVAL_UNDEF(&_5$$3);
	ZVAL_UNDEF(&_6$$4);
	ZVAL_UNDEF(&_7$$5);
	ZVAL_UNDEF(&_8$$5);
	ZVAL_UNDEF(&_9$$5);
	ZVAL_UNDEF(&_11$$6);
	ZVAL_UNDEF(&options);
	ZVAL_UNDEF(&_3$$3);
	static zend_string *_zephir_prop_0 = NULL;
	static zend_string *_zephir_prop_1 = NULL;
	static zend_string *_zephir_prop_2 = NULL;
	static zend_string *_zephir_prop_3 = NULL;
	static zend_string *_zephir_prop_4 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("useEncryption", 13, 1);
	}
	if (UNEXPECTED(!_zephir_prop_1)) {
		_zephir_prop_1 = zend_string_init("cookies", 7, 1);
	}
	if (UNEXPECTED(!_zephir_prop_2)) {
		_zephir_prop_2 = zend_string_init("container", 9, 1);
	}
	if (UNEXPECTED(!_zephir_prop_3)) {
		_zephir_prop_3 = zend_string_init("signKey", 7, 1);
	}
	if (UNEXPECTED(!_zephir_prop_4)) {
		_zephir_prop_4 = zend_string_init("isRegistered", 12, 1);
	}

	bool is_null_true = 1;
	ZEND_PARSE_PARAMETERS_START(1, 8)
		Z_PARAM_STR(name)
		Z_PARAM_OPTIONAL
		Z_PARAM_ZVAL_OR_NULL(value)
		Z_PARAM_LONG(expire)
		Z_PARAM_STR(path)
		Z_PARAM_BOOL(secure)
		Z_PARAM_STR(domain)
		Z_PARAM_BOOL(httpOnly)
		ZEPHIR_Z_PARAM_ARRAY(options, options_param)
	ZEND_PARSE_PARAMETERS_END();
	ZEPHIR_METHOD_GLOBALS_PTR = pecalloc(1, sizeof(zephir_method_globals), 0);
	zephir_memory_grow_stack(ZEPHIR_METHOD_GLOBALS_PTR, __func__);
	if (ZEND_NUM_ARGS() > 1) {
		value = ZEND_CALL_ARG(execute_data, 2);
	}
	if (ZEND_NUM_ARGS() > 2) {
		expire_param = ZEND_CALL_ARG(execute_data, 3);
	}
	if (ZEND_NUM_ARGS() > 4) {
		secure_param = ZEND_CALL_ARG(execute_data, 5);
	}
	if (ZEND_NUM_ARGS() > 6) {
		httpOnly_param = ZEND_CALL_ARG(execute_data, 7);
	}
	if (ZEND_NUM_ARGS() > 7) {
		options_param = ZEND_CALL_ARG(execute_data, 8);
	}
	zephir_memory_observe(&name_zv);
	ZVAL_STR_COPY(&name_zv, name);
	if (!value) {
		value = &value_sub;
		value = &__$null;
	}
	if (!expire_param) {
		expire = 0;
	} else {
		}
	if (!path) {
		path = zend_string_init(ZEND_STRL("/"), 0);
		zephir_memory_observe(&path_zv);
		ZVAL_STR(&path_zv, path);
	} else {
		zephir_memory_observe(&path_zv);
	ZVAL_STR_COPY(&path_zv, path);
	}
	if (!secure_param) {
		secure = 0;
	} else {
		}
	if (!domain) {
		domain = zend_string_init(ZEND_STRL(""), 0);
		zephir_memory_observe(&domain_zv);
		ZVAL_STR(&domain_zv, domain);
	} else {
		zephir_memory_observe(&domain_zv);
	ZVAL_STR_COPY(&domain_zv, domain);
	}
	if (!httpOnly_param) {
		httpOnly = 0;
	} else {
		}
	if (!options_param) {
		ZEPHIR_INIT_VAR(&options);
		array_init(&options);
	} else {
		zephir_get_arrval(&options, options_param);
	}
	zephir_memory_observe(&encryption);
	zephir_read_property_cached(&encryption, this_ptr, _zephir_prop_0, 911, PH_NOISY_CC);
	zephir_memory_observe(&cookie);
	zephir_read_property_cached(&_0, this_ptr, _zephir_prop_1, 912, PH_NOISY_CC | PH_READONLY);
	if (!(zephir_array_isset_fetch(&cookie, &_0, &name_zv, 0))) {
		zephir_read_property_cached(&_1$$3, this_ptr, _zephir_prop_2, 913, PH_NOISY_CC | PH_READONLY);
		ZEPHIR_INIT_VAR(&_3$$3);
		zephir_create_array(&_3$$3, 8, 0);
		zephir_array_fast_append(&_3$$3, &name_zv);
		zephir_array_fast_append(&_3$$3, value);
		ZEPHIR_INIT_VAR(&_4$$3);
		ZVAL_LONG(&_4$$3, expire);
		zephir_array_fast_append(&_3$$3, &_4$$3);
		zephir_array_fast_append(&_3$$3, &path_zv);
		ZEPHIR_INIT_NVAR(&_4$$3);
		ZVAL_BOOL(&_4$$3, secure);
		zephir_array_fast_append(&_3$$3, &_4$$3);
		zephir_array_fast_append(&_3$$3, &domain_zv);
		ZEPHIR_INIT_NVAR(&_4$$3);
		ZVAL_BOOL(&_4$$3, httpOnly);
		zephir_array_fast_append(&_3$$3, &_4$$3);
		zephir_array_fast_append(&_3$$3, &options);
		ZEPHIR_INIT_NVAR(&_4$$3);
		ZVAL_STRING(&_4$$3, "Phalcon\\Http\\Cookie");
		ZEPHIR_CALL_METHOD(&_2$$3, &_1$$3, "get", NULL, 0, &_4$$3, &_3$$3);
		zephir_check_call_status();
		ZEPHIR_CPY_WRT(&cookie, &_2$$3);
		zephir_read_property_cached(&_5$$3, this_ptr, _zephir_prop_2, 913, PH_NOISY_CC | PH_READONLY);
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setdi", NULL, 0, &_5$$3);
		zephir_check_call_status();
		if (zephir_is_true(&encryption)) {
			ZEPHIR_CALL_METHOD(NULL, &cookie, "useencryption", NULL, 0, &encryption);
			zephir_check_call_status();
			zephir_read_property_cached(&_6$$4, this_ptr, _zephir_prop_3, 914, PH_NOISY_CC | PH_READONLY);
			ZEPHIR_CALL_METHOD(NULL, &cookie, "setsignkey", NULL, 0, &_6$$4);
			zephir_check_call_status();
		}
		zephir_update_property_array(this_ptr, SL("cookies"), &name_zv, &cookie);
	} else {
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setvalue", NULL, 0, value);
		zephir_check_call_status();
		ZVAL_LONG(&_7$$5, expire);
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setexpiration", NULL, 0, &_7$$5);
		zephir_check_call_status();
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setpath", NULL, 0, &path_zv);
		zephir_check_call_status();
		if (secure) {
			ZVAL_BOOL(&_7$$5, 1);
		} else {
			ZVAL_BOOL(&_7$$5, 0);
		}
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setsecure", NULL, 0, &_7$$5);
		zephir_check_call_status();
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setdomain", NULL, 0, &domain_zv);
		zephir_check_call_status();
		if (httpOnly) {
			ZVAL_BOOL(&_8$$5, 1);
		} else {
			ZVAL_BOOL(&_8$$5, 0);
		}
		ZEPHIR_CALL_METHOD(NULL, &cookie, "sethttponly", NULL, 0, &_8$$5);
		zephir_check_call_status();
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setoptions", NULL, 0, &options);
		zephir_check_call_status();
		zephir_read_property_cached(&_9$$5, this_ptr, _zephir_prop_3, 914, PH_NOISY_CC | PH_READONLY);
		ZEPHIR_CALL_METHOD(NULL, &cookie, "setsignkey", NULL, 0, &_9$$5);
		zephir_check_call_status();
	}
	zephir_read_property_cached(&_10, this_ptr, _zephir_prop_4, 916, PH_NOISY_CC | PH_READONLY);
	if (ZEPHIR_IS_FALSE_IDENTICAL(&_10)) {
		ZEPHIR_CALL_METHOD(&container, this_ptr, "checkgetcontainer", NULL, 0);
		zephir_check_call_status();
		ZEPHIR_INIT_VAR(&_11$$6);
		ZVAL_STRING(&_11$$6, "response");
		ZEPHIR_CALL_METHOD(&response, &container, "getshared", NULL, 0, &_11$$6);
		zephir_check_call_status();
		ZEPHIR_CALL_METHOD(NULL, &response, "setcookies", NULL, 0, this_ptr);
		zephir_check_call_status();
		if (1) {
			zephir_update_property_zval_cached(this_ptr, _zephir_prop_4, 916, &__$true);
		} else {
			zephir_update_property_zval_cached(this_ptr, _zephir_prop_4, 916, &__$false);
		}
	}
	RETURN_THIS();
}

/**
 * Sets the cookie's sign key.
 *
 * The `$signKey' MUST be at least 32 characters long
 * and generated using a cryptographically secure pseudo random generator.
 *
 * Use NULL to disable cookie signing.
 *
 * @see \Phalcon\Encryption\Security\Random
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, setSignKey)
{
	zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
	zval signKey_zv;
	zend_string *signKey = NULL;
	zval *this_ptr = getThis();

	ZVAL_UNDEF(&signKey_zv);
	static zend_string *_zephir_prop_0 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("signKey", 7, 1);
	}

	bool is_null_true = 1;
	ZEND_PARSE_PARAMETERS_START(0, 1)
		Z_PARAM_OPTIONAL
		Z_PARAM_STR_OR_NULL(signKey)
	ZEND_PARSE_PARAMETERS_END();
	ZEPHIR_METHOD_GLOBALS_PTR = pecalloc(1, sizeof(zephir_method_globals), 0);
	zephir_memory_grow_stack(ZEPHIR_METHOD_GLOBALS_PTR, __func__);
	if (!signKey) {
		ZEPHIR_INIT_VAR(&signKey_zv);
	} else {
		zephir_memory_observe(&signKey_zv);
	ZVAL_STR_COPY(&signKey_zv, signKey);
	}
	zephir_update_property_zval_cached(this_ptr, _zephir_prop_0, 914, &signKey_zv);
	RETURN_THIS();
}

/**
 * Set if cookies in the bag must be automatically encrypted/decrypted
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, useEncryption)
{
	zval *useEncryption_param = NULL, __$true, __$false;
	zend_bool useEncryption;
	zval *this_ptr = getThis();

	ZVAL_BOOL(&__$true, 1);
	ZVAL_BOOL(&__$false, 0);
	static zend_string *_zephir_prop_0 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("useEncryption", 13, 1);
	}

	ZEND_PARSE_PARAMETERS_START(1, 1)
		Z_PARAM_BOOL(useEncryption)
	ZEND_PARSE_PARAMETERS_END();
	zephir_fetch_params_without_memory_grow(1, 0, &useEncryption_param);
	if (useEncryption) {
		zephir_update_property_zval_cached(this_ptr, _zephir_prop_0, 911, &__$true);
	} else {
		zephir_update_property_zval_cached(this_ptr, _zephir_prop_0, 911, &__$false);
	}
	RETURN_THISW();
}

PHP_METHOD(Phalcon_Http_Response_Cookies, checkGetContainer)
{
	zval container, _0, _1$$3;
	zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
	zend_long ZEPHIR_LAST_CALL_STATUS;
	zval *this_ptr = getThis();

	ZVAL_UNDEF(&container);
	ZVAL_UNDEF(&_0);
	ZVAL_UNDEF(&_1$$3);
	static zend_string *_zephir_prop_0 = NULL;
	if (UNEXPECTED(!_zephir_prop_0)) {
		_zephir_prop_0 = zend_string_init("container", 9, 1);
	}
	ZEPHIR_METHOD_GLOBALS_PTR = pecalloc(1, sizeof(zephir_method_globals), 0);
	zephir_memory_grow_stack(ZEPHIR_METHOD_GLOBALS_PTR, __func__);

	zephir_read_property_cached(&_0, this_ptr, _zephir_prop_0, 913, PH_NOISY_CC | PH_READONLY);
	ZEPHIR_CPY_WRT(&container, &_0);
	if (Z_TYPE_P(&container) == IS_NULL) {
		ZEPHIR_INIT_VAR(&_1$$3);
		object_init_ex(&_1$$3, phalcon_http_response_exceptions_responseserviceunavailable_ce);
		ZEPHIR_CALL_METHOD(NULL, &_1$$3, "__construct", NULL, 0);
		zephir_check_call_status();
		zephir_throw_exception_debug(&_1$$3, "phalcon/Http/Response/Cookies.zep", 357);
		ZEPHIR_MM_RESTORE();
		return;
	}
	RETURN_CCTOR(&container);
}

/**
 * Check if implicit encryption is being used
 */
PHP_METHOD(Phalcon_Http_Response_Cookies, isUsingEncryption)
{

	RETURN_MEMBER(getThis(), "useEncryption");
}

