/**********************************************************************
 * LeechCraft - modular cross-platform feature rich internet client.
 * Copyright (C) 2006-2014  Georg Rudoy
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **********************************************************************/

#pragma once

#include <QNetworkCookieJar>
#include <QByteArray>
#include <QRegExp>
#include "networkconfig.h"

namespace LC
{
namespace Util
{
	/** @brief A customized cookie jar with additional features.
	 *
	 * Allows one to filter tracking cookies, filter duplicate cookies
	 * and has unlimited storage period.
	 *
	 * @ingroup NetworkUtil
	 */
	class UTIL_NETWORK_API CustomCookieJar : public QNetworkCookieJar
	{
		Q_OBJECT

		bool FilterTrackingCookies_ = false;
		bool Enabled_ = true;
		bool MatchDomainExactly_ = false;

		QList<QRegExp> WL_;
		QList<QRegExp> BL_;
	public:
		/** @brief Constructs the cookie jar.
		 *
		 * Filtering of tracking cookies is false by default, and
		 * cookies aren't restored.
		 *
		 * @param[in] parent The parent object.
		 */
		explicit CustomCookieJar (QObject *parent = nullptr);

		/** Enables or disables filtering tracking cookies.
		 *
		 * @param[in] filter Whether to filter tracking cookies.
		 */
		void SetFilterTrackingCookies (bool filter);

		/** @brief Enables or disables the cookies.
		 *
		 * If cookie jar is disabled, no new cookies will be saved and
		 * no cookies will be returned for any URL.
		 *
		 * @param[in] enabled Whether the cookie jar should be
		 * enabled.
		 */
		void SetEnabled (bool enabled);

		/** @brief Sets whether exact domain matching is enabled.
		 *
		 * @param[in] enabled Whether exact matching is enabled.
		 */
		void SetExactDomainMatch (bool enabled);

		/** @brief Sets the cookies whitelist.
		 *
		 * Cookies whose domains match regexps from the list will always
		 * be accepted even despite the SetFilterTrackingCookies() and
		 * SetExactDomainMatch() settings.
		 *
		 * If a cookie domain matches both a whitelist regexp and
		 * blacklist regexp, it is accepted.
		 *
		 * If cookies are disabled via SetEnabled(), this option has no
		 * effect.
		 *
		 * @param[in] list The whitelist.
		 *
		 * @sa SetBlacklist()
		 */
		void SetWhitelist (const QList<QRegExp>& list);

		/** @brief Sets the cookies blacklist.
		 *
		 * Cookies whose domains match regexps from the list will always
		 * be rejected until they are also present in the whitelist, in
		 * which case they are accepted.
		 *
		 * @param[in] list The blacklist.
		 *
		 * @sa SetWhitelist()
		 */
		void SetBlacklist (const QList<QRegExp>& list);

		/** Serializes the cookie jar contents into a QByteArray
		 * suitable for storage.
		 *
		 * @return The serialized cookies.
		 *
		 * @sa Load()
		 */
		[[nodiscard]] QByteArray Save () const;

		/** Restores the cookies from the array previously obtained
		 * from Save().
		 *
		 * @param[in] data Serialized cookies.
		 * @sa Save()
		 */
		void Load (const QByteArray& data);

		/** Removes duplicate cookies.
		 */
		void CollectGarbage ();

		/** @brief Returns cookies for the given url.
		 *
		 * This function automatically filters out duplicate cookies.
		 *
		 * If the cookie jar is disabled, this function does nothing.
		 *
		 * @param[in] url The url to return cookies for.
		 * @return The list of cookies, dup-free.
		 */
		QList<QNetworkCookie> cookiesForUrl (const QUrl& url) const override;

		/** @brief Adds the cookieList for the given url to the jar.
		 *
		 * If the cookie jar is disabled, this function does nothing.
		 *
		 * @param[in] cookieList The list of cookies to add.
		 * @param[in] url The url to set cookies for.
		 * @return Whether the jar has been modified as the result.
		 */
		bool setCookiesFromUrl (const QList<QNetworkCookie>& cookieList, const QUrl& url) override;

		using QNetworkCookieJar::allCookies;
		using QNetworkCookieJar::setAllCookies;
	signals:
		void cookiesAdded (const QList<QNetworkCookie>&);
		void cookiesRemoved (const QList<QNetworkCookie>&);
	};
}
}
