/*
 * Copyright (c) 2010-2022 Belledonne Communications SARL.
 *
 * This file is part of Liblinphone 
 * (see https://gitlab.linphone.org/BC/public/liblinphone).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif // _MSC_VER

#ifndef _CONTENT_HH
#define _CONTENT_HH

#include <cstdint>
#include <string>
#include <list>
#include "object.hh"




struct _LinphoneContent;


namespace linphone {

	class Content;

	/**
	 * @brief This object holds data that can be embedded in a signaling message. 
	 *
	 * Use Core::createContent() to create it, and then you should set at least it's
	 * type and subtype and fill the buffer with your data.
	 * A @ref Content can be multipart (contain other contents), have file information
	 * (name, path, size), be encrypted, have custom headers, etc...
	 * It is mainly used to send information through a @ref ChatMessage. 
	 */
	class Content: public Object {
	
		public:

			LINPHONECXX_PUBLIC Content(void *ptr, bool takeRef=true);
			LINPHONECXX_PUBLIC _LinphoneContent *cPtr() {return (_LinphoneContent *)mPrivPtr;}

	
		public:
			
		
			/**
			 * @brief Get the content data buffer, usually a string. 
			 *
			 * @return The content data buffer.    
			 */
			LINPHONECXX_PUBLIC const uint8_t * getBuffer() const;
			
			/**
			 * @brief Get the disposition of the Content, for example "recipient-list". 
			 *
			 * @return The disposition of the Content.    
			 */
			LINPHONECXX_PUBLIC std::string getDisposition() const;
			
			/**
			 * @brief Set the disposition of the Content, for example "recipient-list". 
			 *
			 * @param disposition The disposition of the Content.    
			 */
			LINPHONECXX_PUBLIC void setDisposition(const std::string & disposition);
			
			/**
			 * @brief Get the encoding of the data buffer, for example "gzip". 
			 *
			 * @return The encoding of the data buffer.    
			 */
			LINPHONECXX_PUBLIC std::string getEncoding() const;
			
			/**
			 * @brief Set the encoding of the data buffer, for example "gzip". 
			 *
			 * @param encoding The encoding of the data buffer.    
			 */
			LINPHONECXX_PUBLIC void setEncoding(const std::string & encoding);
			
			/**
			 * @brief Gets the file duration in seconds, if information is available. 
			 *
			 * @return The duration of the file in seconds or -1 if information isn't
			 * available. 
			 */
			LINPHONECXX_PUBLIC int getFileDuration();
			
			/**
			 * @brief Get the file transfer filepath set for this content (replace
			 * linphone_chat_message_get_file_transfer_filepath). 
			 *
			 * @return The file path set for this content if it has been set, nullptr
			 * otherwise.    
			 */
			LINPHONECXX_PUBLIC std::string getFilePath() const;
			
			/**
			 * @brief Set the file transfer filepath for this content (replace
			 * linphone_chat_message_set_file_transfer_filepath). 
			 *
			 * @param filePath the file transfer filepath.    
			 */
			LINPHONECXX_PUBLIC void setFilePath(const std::string & filePath);
			
			/**
			 * @brief Get the file size if content is either a FileContent or a
			 * FileTransferContent. 
			 *
			 * @return The represented file size. 
			 */
			LINPHONECXX_PUBLIC size_t getFileSize() const;
			
			/**
			 * @brief Tells whether or not this content contains a file. 
			 *
			 * @return true if this content contains a file, false otherwise. 
			 */
			LINPHONECXX_PUBLIC bool isFile() const;
			
			/**
			 * @brief Tells whether or not this content contains an encrypted file. 
			 *
			 * @return True is this content contains a file and this file is encrypted, false
			 * otherwise. 
			 */
			LINPHONECXX_PUBLIC bool isFileEncrypted() const;
			
			/**
			 * @brief Tells whether or not this content is a file transfer. 
			 *
			 * @return true if this content is a file transfer, false otherwise. 
			 */
			LINPHONECXX_PUBLIC bool isFileTransfer() const;
			
			/**
			 * @brief Tells whether or not this content contains an icalendar by checking it's
			 * content type. 
			 *
			 * @return true if this content type is 'text/calendar;conference-event=yes',
			 * false otherwise. 
			 */
			LINPHONECXX_PUBLIC bool isIcalendar() const;
			
			/**
			 * @brief Tell whether a content is a multipart content. 
			 *
			 * @return A boolean value telling whether the content is multipart or not. 
			 */
			LINPHONECXX_PUBLIC bool isMultipart() const;
			
			/**
			 * @brief Tells whether or not this content contains text. 
			 *
			 * @return true if this content contains plain text, false otherwise. 
			 */
			LINPHONECXX_PUBLIC bool isText() const;
			
			/**
			 * @brief Tells whether or not this content contains a voice recording by checking
			 * it's content type. 
			 *
			 * @return true if this content type is 'audio/wav;voice-recording=yes', false
			 * otherwise. 
			 */
			LINPHONECXX_PUBLIC bool isVoiceRecording() const;
			
			/**
			 * @brief Get the key associated with a RCS file transfer message if encrypted. 
			 *
			 * @return The key to encrypt/decrypt the file associated to this content.    
			 */
			LINPHONECXX_PUBLIC std::string getKey() const;
			
			/**
			 * @brief Get the size of key associated with a RCS file transfer message if
			 * encrypted. 
			 *
			 * @return The key size in bytes 
			 */
			LINPHONECXX_PUBLIC size_t getKeySize() const;
			
			/**
			 * @brief Get the name associated with a RCS file transfer message. 
			 *
			 * It is used to store the original filename of the file to be downloaded from
			 * server. 
			 * @return The name of the content.    
			 */
			LINPHONECXX_PUBLIC std::string getName() const;
			
			/**
			 * @brief Set the name associated with a RCS file transfer message. 
			 *
			 * It is used to store the original filename of the file to be downloaded from
			 * server. 
			 * @param name The name of the content.    
			 */
			LINPHONECXX_PUBLIC void setName(const std::string & name);
			
			/**
			 * @brief Get all the parts from a multipart content. 
			 *
			 * @return A   object holding the part if found, nullptr otherwise.       
			 */
			LINPHONECXX_PUBLIC std::list<std::shared_ptr<linphone::Content>> getParts() const;
			
			/**
			 * @brief Generates a temporary plain copy of the file and returns its paths The
			 * caller is responsible to then delete this temporary copy and the returned
			 * string. 
			 *
			 * @return The file path set for this content if it has been set, nullptr
			 * otherwise.    
			 * @deprecated 2022-01-07. Use exportPlainFile() instead. 
			 */
			LINPHONECXX_PUBLIC LINPHONECXX_DEPRECATED std::string getPlainFilePath() const;
			
			/**
			 * @brief Get the content data buffer size, excluding null character despite null
			 * character is always set for convenience. 
			 *
			 * @return The content data buffer size. 
			 */
			LINPHONECXX_PUBLIC size_t getSize() const;
			
			/**
			 * @brief Set the content data size, excluding null character despite null
			 * character is always set for convenience. 
			 *
			 * @param size The content data buffer size. 
			 */
			LINPHONECXX_PUBLIC void setSize(size_t size);
			
			/**
			 * @brief Get the string content data buffer. 
			 *
			 * @return The string content data buffer.    
			 * @deprecated 2020-07-01. Use getUtf8Text() instead. 
			 */
			LINPHONECXX_PUBLIC LINPHONECXX_DEPRECATED std::string getStringBuffer() const;
			
			/**
			 * @brief Set the string content data buffer. 
			 *
			 * @param buffer The string content data buffer in UTF8.    
			 * @deprecated 2020-07-01. Use setUtf8Text() instead. 
			 */
			LINPHONECXX_PUBLIC LINPHONECXX_DEPRECATED void setStringBuffer(const std::string & buffer);
			
			/**
			 * @brief Get the mime subtype of the content data. 
			 *
			 * @return The mime subtype of the content data, for example "html".    
			 */
			LINPHONECXX_PUBLIC std::string getSubtype() const;
			
			/**
			 * @brief Set the mime subtype of the content data. 
			 *
			 * @param subtype The mime subtype of the content data, for example "html".    
			 */
			LINPHONECXX_PUBLIC void setSubtype(const std::string & subtype);
			
			/**
			 * @brief Get the mime type of the content data. 
			 *
			 * @return The mime type of the content data, for example "application".    
			 */
			LINPHONECXX_PUBLIC std::string getType() const;
			
			/**
			 * @brief Set the mime type of the content data. 
			 *
			 * @param type The mime type of the content data, for example "application".    
			 */
			LINPHONECXX_PUBLIC void setType(const std::string & type);
			
			/**
			 * @brief Get the string content data buffer. 
			 *
			 * Introduced in 01/07/2020 
			 * @return The string content data buffer in UTF8.    
			 */
			LINPHONECXX_PUBLIC std::string getUtf8Text() const;
			
			/**
			 * @brief Get the string content data buffer. 
			 *
			 * Introduced in 01/07/2020 
			 * @param buffer The string content data buffer in UTF8.    
			 */
			LINPHONECXX_PUBLIC void setUtf8Text(const std::string & buffer);
			
			/**
			 * @brief Adds a parameter to the ContentType header. 
			 *
			 * @param name the name of the parameter to add.    
			 * @param value the value of the parameter to add.    
			 */
			LINPHONECXX_PUBLIC void addContentTypeParameter(const std::string & name, const std::string & value);
			
			/**
			 * @brief Adds a custom header in a content. 
			 *
			 * @param headerName The name of the header to add.    
			 * @param headerValue The value of the header to add.    
			 */
			LINPHONECXX_PUBLIC void addCustomHeader(const std::string & headerName, const std::string & headerValue);
			
			/**
			 * @brief Generates a temporary plain copy of the file and returns its paths The
			 * caller is responsible to then delete this temporary copy and the returned
			 * string. 
			 *
			 * @return The file path set for this content if it has been set, nullptr
			 * otherwise.    
			 */
			LINPHONECXX_PUBLIC std::string exportPlainFile() const;
			
			/**
			 * @brief Find a part from a multipart content looking for a part header with a
			 * specified value. 
			 *
			 * @param headerName The name of the header to look for.    
			 * @param headerValue The value of the header to look for.    
			 * @return A @ref Content object object the part if found, nullptr otherwise.    
			 */
			LINPHONECXX_PUBLIC std::shared_ptr<linphone::Content> findPartByHeader(const std::string & headerName, const std::string & headerValue) const;
			
			/**
			 * @brief Get a custom header value of a content. 
			 *
			 * @param headerName The name of the header to get the value from.    
			 * @return The value of the header if found, nullptr otherwise.    
			 */
			LINPHONECXX_PUBLIC std::string getCustomHeader(const std::string & headerName) const;
			
			/**
			 * @brief Get a part from a multipart content according to its index. 
			 *
			 * @param index The index of the part to get. 
			 * @return A @ref Content object holding the part if found, nullptr otherwise.    
			 */
			LINPHONECXX_PUBLIC std::shared_ptr<linphone::Content> getPart(int index) const;
			
			/**
			 * @brief Set the content data buffer, usually a string. 
			 *
			 * @param buffer The content data buffer.    
			 * @param size The size of the content data buffer. 
			 */
			LINPHONECXX_PUBLIC void setBuffer(const uint8_t * buffer, size_t size);
			
			/**
			 * @brief Set the key associated with a RCS file transfer message if encrypted. 
			 *
			 * @param key The key to be used to encrypt/decrypt file associated to this
			 * content.    
			 * @param keyLength The lengh of the key. 
			 */
			LINPHONECXX_PUBLIC void setKey(const std::string & key, const size_t keyLength);
			
			
	};

};

#endif // _CONTENT_HH

#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif // _MSC_VER
