//
// This file is part of the aMule AdunanzA Project (mod of official aMule)
//
// Copyright (c) 2003-2008 aMule AdunanzA Team ( http://www.adunanza.net )
//
// Any parts of this program derived from the xMule, lMule, eMule or aMule project,
// or contributed by third-party developers are copyrighted by their
// respective authors.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 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 General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
//

#if !defined(_ADUNANZA_H_)
#define _ADUNANZA_H_

#ifdef HAVE_CONFIG_H
	#include "config.h"			//   VERSION
#endif


#include <queue>   // Mr Hyde
#include "Types.h" // Mr Hyde



//////////////////////////////////////////////////////////////////////////////////////
//
#define ADU_MOD_NAME _T("AdunanzA")

#define ADU_VER_MAJ   2011 
#define ADU_VER_MIN   1

// IMPOSTARE LA SEG. ADU_BETA_MAJ A 0 PER LE VERSIONI RILASCIATE UFFICIALMENTE 
#define ADU_BETA_MAJ 1
#define ADU_BETA_MIN
//
//////////////////////////////////////////////////////////////////////////////////////



#define V(M, m) _T(#M) _T(".") _T(#m)
#define _V(M, m) V(M,m)

// Per il momento lascio perdere _T(l)
// #define B(n, l) _T(#n) _T(l)
#define B(n, l) _T(#n)

#define _B(n, l) B(n, l)


#define ADU_VER_RL _V(ADU_VER_MAJ, ADU_VER_MIN)

#if ADU_BETA_MAJ > 0
	#define ADU_VER ADU_VER_RL _T("b") _B(ADU_BETA_MAJ, ADU_BETA_MIN)
#else
	#define ADU_VER ADU_VER_RL
#endif

#define ADU_MOD ADU_MOD_NAME _T(" ") ADU_VER

// Mr Hyde: uso la seg. per avere "aMuleAdunanzA" invece di "aMule" come nome
// di directory (es: directory per preferenze diventa ~/.aMuleAdunanzA)
#define ADU_APPNAME "aMuleAdunanzA"
#define AMULE_ADUNANZA_DIR ADU_APPNAME

// Mr Hyde: usata per gestione lingue
// deve corrispondere:
// - al file .pot e ai file .gmo generati
// - al primo argomento della macro AC_INIT (o meglio, al lowercase del primo argomento di AC_INIT, vedi file "configure.in")
#if !defined(PACKAGE_ADUNANZA)
#define PACKAGE_ADUNANZA "amuleadunanza"
#endif

// Mr Hyde: rimosse le define di MOD_VERSION_LONG perche' definite in src/include/common/ClientVersion.h
//

// Parametri e definzioni esportate dal file AdunanzA.cpp
#define ADUNANZA_ANY            0
#define ADUNANZA_EXTERN         1
#define ADUNANZA_FASTWEB        2
#define ADUNANZA_NONE           0xff

// Definizioni per icone e per riconoscimento client
#define ADUNANZA_ICON_NONE      0
#define ADUNANZA_ICON_FW        1
#define ADUNANZA_ICON_ADU       2

// Percentuale minima per assegnare uno slot ad un Adu
//#define ADUNANZA_MIN_ADU	5
// Definizione default del numero di slots
#define ADUNANZA_DEF_UPSL	8
// Definizione default banda Adu
#define ADUNANZA_BAND_PERC  (85) // Mr Hyde allineamento 3.16, ripartitore banda
#define ADUNANZA_DEF_BW_EXT  (6) // Mr Hyde allineamento 3.16, ripartitore banda

const uint32 ADU_MAX_RATIO_KADU_DOWN(3145728); // 3 mega * 1024 KB in mega * 1024 byte in KB
const uint32 ADUNANZA_MIN_BW_TROLLER(2);

const bool ADUNANZA_UP_EXT_CHECK(false); // il default per abilitare le impostazioni CUSTOM del ripartitore di banda deve essere false (ovvero: custom DISABILITATO) 

const unsigned int ADU_EXT_FULL_WAIT_TIME(480); // 8 minuti

// Definizione connessione automatica
#define ADUNANZA_AUTO_CONN	1
// Definizione forzature upload/dl ext 1:1 - Disabilitato di default
#define ADUNANZA_AUTO_EXT11	1

#define ADU_VER_CODE(M,m,o) (((M) << 12) + ((m) << 7) + (o))
#define ADU_GET_MAJ(v) ((v) >> 12)
#define ADU_GET_MIN(v) (((v) >> 7) & 0x1f)
#define ADU_GET_B(v) ((v) & 0x7f)

// ADU URLS
#define ADURM_URL              "http://update.adunanza.net/3-16/adu_remote.conf"

// Mr Hyde: cambiato su richiesta di Hammon
#define ADU_SRV_URL            "http://update.adunanza.net/servers.met"

// Mr Hyde: 29 Maggio 2008
// Sul forum di aMule ho letto di alcuni utenti che hanno avuto problemi 
// con il vecchio formato.
// Personalmente dubito che il vecchio formato possa dare problemi,
// pero' per sicurezza ho comunque aggiornato al nuovo indirizzo con KAD2
// #define ADU_NODES_DAT          "http://update.adunanza.net/amule/adu_nodes.dat"
#define ADU_NODES_DAT          "http://www.adunanza.net/files/emule/adu_nodes.dat"

// Mr Hyde per allineamento 3.15
// Remote IPFilter by Tigerjact
#define ADU_REMOTE_FILTER       "http://update.adunanza.net/adu_remoteipfilter.dat"

#define ADU_KEYWORDS_FILE "key_np.dat"


# if ADU_BETA_MAJ > 0
#	define ADU_ADUNANZANET_URL    "http://forum.adunanza.net/showthread.php?t=49167" // Mr Hyde
# else
#	define ADU_ADUNANZANET_URL    "http://www.adunanza.net" // da mettere quando non sara' piu' una beta 
# endif

// Mr Hyde: aggiunto
// notare che l'URL scritto in questo modo NON rispetta il draft per gli URL IRC
// (dovrebbe avere il carattere "#" dato come %23, ci sto studiando)
//
// Mr Hyde, 20100125, cambiato l'indirizzo su richiesta di Hammon
#define ADU_IRCHELP_URL        "irc://chat.adunanza.net:6667/#Linux"

// Mr Hyde: per default programma IRC (da sistemare per MAC)
#define ADU_DEFAULT_IRC       "xchat"
// Mr Hyde, 20100125, cambiato l'indirizzo su richiesta di Hammon
#define ADU_DEFAULT_IRC_FLAGS "--url irc://chat.adunanza.net:6667/#Linux"

// Mr Hyde: per pagina da associare a F1
// Mr Hyde, 20100125, cambiato l'indirizzo su richiesta di Hammon
#define ADU_WIKI_URL           "http://aduteca.adunanza.net/Amule_AdunanzA"

// Aggiunto test porte
#define ADU_PORTTEST_BASE_URL       "http://adutest.adunanza.net/emule_testport/adutest.php?tcp=%d&udp=%d"

/*
MAN Milano........................   1.0.0.0/8
MAN Milano hinterland Nord........   2.0.0.0/8
MAN Genova........................   5.0.0.0/8
MAN Veneto........................  11.0.0.0/8
MAN Milano hinterland Sud.........  14.0.0.0/8
MAN Ancona........................  21.0.0.0/8
MAN Grosseto......................  22.0.0.0/8
MAN Roma..........................  23.0.0.0/8
MAN Toscana.......................  27.0.0.0/8
MAN Piemonte......................  28.0.0.0/8
MAN Triveneto.....................  29.0.0.0/8
MAN Bari..........................  31.0.0.0/8
MAN Sicilia.......................  36.0.0.0/8
MAN Bologna.......................  37.0.0.0/8
MAN Napoli........................  39.0.0.0/8
MAN Torino........................  41.0.0.0/8
MAN Reggio Emilia.................  42.0.0.0/8
MAN Cagliari......................  51.0.0.0/8

Routers & OAM.....................  10.0.0.0/8
Organization, Administration & Management (ad. es.: Server interni ntp, voip, billing etc. etc.)
*/

// Definizione zone italia FW
#define MAN_MILANO         1
#define MAN_MILANO_H_NORD  2
#define MAN_GENOVA         5
#define FASTWEB_ROUTERS   10
#define MAN_VENETO        11
#define MAN_MILANO_H_SUD  14
#define MAN_ANCONA        21
#define MAN_GROSSETO      22
#define MAN_ROMA          23
#define MAN_TOSCANA       27
#define MAN_PIEMONTE      28
#define MAN_TRIVENETO     29
#define MAN_BARI          31
#define MAN_SICILIA       36
#define MAN_BOLOGNA       37
#define MAN_NAPOLI        39
#define MAN_TORINO        41
#define MAN_REGGIO_EMILIA 42
#define MAN_CAGLIARI      51

class wxString;

// Funzioni esportate


class CAdunanzAUtilities {
	public:
		static inline bool AduIsFastWebLANIP(uint32 ip)
		{
			switch (ip & 0xff) {
				case MAN_ROMA:
				case MAN_MILANO:
				case MAN_MILANO_H_NORD:
				case MAN_MILANO_H_SUD:
				case MAN_GENOVA:
				case MAN_TRIVENETO:
				case MAN_BARI:
				case MAN_BOLOGNA:
				case MAN_NAPOLI:
				case MAN_TORINO:
				case MAN_REGGIO_EMILIA:
				case MAN_TOSCANA:
				case MAN_PIEMONTE:
				case MAN_VENETO:
				case MAN_GROSSETO:
				case MAN_SICILIA:
				case MAN_ANCONA:
				case MAN_CAGLIARI:
				case FASTWEB_ROUTERS:
					return true;
				default:
					return false;
			}
		}


		static bool AduIsFastWebIP(uint32 ip)
		{
			if (CAdunanzAUtilities::AduIsFastWebLANIP(ip)) 
				return true;
			
			// match rapido: (ip & mask) == netid

			// netid 213.140.0.0/19			- netid (hex) 0x00008cd5 / mask 0x00e0ffff
			if ((ip & 0x00e0ffff) == 0x00008cd5 ||
			// netid 213.156.32.0/19		- netid (hex) 0x00209cd5 / mask 0x00e0ffff
					(ip & 0x00e0ffff) == 0x00209cd5 ||
			// netid 62.101.64.0/18			- netid (hex) 0x0040653e / mask 0x00c0ffff
					(ip & 0x00c0ffff) == 0x0040653e ||
			// netid 81.208.0.0/17			-	netid (hex) 0x0000d051 / mask 0x0080ffff
					(ip & 0x0080ffff) == 0x0000d051 ||
			// netid 83.103.0.0/17			- netid (hex) 0x00006753 / mask 0x0080ffff
					(ip & 0x0080ffff) == 0x00006753 ||
			// netid 85.18.0.0/16       - netid (hex) 0x00001255 / mask 0x0000ffff
					(ip & 0x0000ffff) == 0x00001255 ||
			// netid 89.96.0.0/15       - netid (hex) 0x00006059 / mask 0x0000f7ff
					(ip & 0x0000f7ff) == 0x00006059 ||
			// netid 93.32.0.0/11       - netid (hex) 0x0000205d / mask 0x0000e0ff  // Allineamento 3.15b74
					(ip & 0x0000e0ff) == 0x0000205d)
					return true;


			return false;
		}
		static bool AduIsFastWebIP(const wxString& ipv4string);

		static bool	AduIsFiber(uint32 ip);
		static uint32	AduGetTypeBand();
		//extern float	AduGetPercBandwidth();
		static void	AduStartConnection();
		static void	AduUpdate(char *url);
		// KAdu
		static bool     AduIsValidKaduAddress( uint32 host );


#ifndef CLIENT_GUI
		static uint32 getAllowedUploadDataRate();

		static float calcolaStima( float input_avail, uint32& firstPublish, uint32 publishInterval, uint32 pubkRTK, bool sameIP, uint32 now );
		static float normalizzaStima( float avail, uint32 from, uint32 to );

		static int AduQ();
		static int ExtQ();
		static bool AduDebt();

		static int OLDSetSlots();
		static int SetSlots();
		static int TotSlots();
#if 0		
		static int ExtSlots();
#endif
		
		static uint32 AduNextClient(int fix = 0);
		static bool AduMaxTrans();
		static uint32 AduGetMaxUploadSlots();

		static void CalcolaRatio(bool bAtMomentNotUsed);
#endif
};


class CAduUploadSlotsManager
{
	public:
		/**
		 * Numero slot disponibili per client esterni (NON AdunanzA)
		 */ 
		uint32 m_externSlots;

		/**
		 * Numero slot disponibili per client AdunanzA
		 */ 
		uint32 m_adunanzaSlots;

		/**
		 * Numero slot "prestati" a AdunanzA
		 *
		 * Considero AdunanzA in debito verso gli esterni quando
		 * gli slot disponibili per AdunanzA sono "0" ma comunque,
		 * per qualche motivo, lo slot viene assegnato ad un client AdunanzA
		 * invece che ad un client esterno.
		 *
		 */ 
		uint32 m_adunanzaDebt;

		/**
		 * Numero slot "prestati" a esterni
		 *
		 * Considero gli esterni in debito verso AdunanzA quando
		 * gli slot disponibili per esterni sono "0" ma comunque,
		 * per qualche motivo, lo slot viene assegnato ad un client esterno
		 * invece che ad un client AdunanzA.
		 *
		 */ 
		uint32 m_externDebt;
	public:
		CAduUploadSlotsManager() :
			m_externSlots(0),
			m_adunanzaSlots(0),
       			m_adunanzaDebt(0),
			m_externDebt(0)
		{}

		~CAduUploadSlotsManager() {};

		// Mr Hyde: per ricavare l'upload rate corrente
		// (codice copiato da UploadBandwidthThrottler.cpp)
		static uint32 getAllowedUploadDataRate();


		uint32 next() const;

		void update(CClientPtrList& uploadingList);

};




#endif


