#pragma once
#include <string>

enum NatBehavior
{
    UnknownBehavior,
    DirectMapping,                  // IP address and port are the same between client and server view (NO NAT)
    EndpointIndependentMapping,     // same mapping regardless of IP:port original packet sent to (the kind of NAT we like)
    AddressDependentMapping,        // mapping changes for local socket based on remote IP address only, but remote port can change (partially symmetric, not great)
    AddressAndPortDependentMapping  // different port mapping if the ip address or port change (symmetric NAT, difficult to predict port mappings)
};

enum NatFiltering
{
    UnknownFiltering,
    DirectConnectionFiltering,
    EndpointIndependentFiltering,    // shouldn't be common unless connection is already direct (can receive on mapped address from anywhere regardless of where the original send went)
    AddressDependentFiltering,       // IP-restricted NAT
    AddressAndPortDependentFiltering // port-restricted NAT
};

enum NAT_TYPE
{
	NAT_UnknownType,
	NAT_DirectMapping,
	NAT_FullCone,
	NAT_IpRestricted,
	NAT_PortRestricted,
	NAT_Symmetric
};

//先检测behavior，再检测filtering,结合2者判断
/*
   1、NAT_BEHAVIOR_UnknownBehavior  不用继续测
   2、AT_BEHAVIOR_DirectMapping   直连，没有nat,不用继续测
   3、NAT_BEHAVIOR_EndpointIndependentMapping
	 1）NAT_Filtering_UnknownFiltering  未定义
	 2）NAT_Filtering_DirectConnectionFiltering, 没有过滤，认为全锥形
	 3）NAT_Filtering_EndpointIndependentFiltering, 端口无关过滤，对应全锥形
	 4）NAT_Filtering_AddressDependentFiltering,    地址依赖过滤，认为是地址受限锥形
	 5）NAT_Filtering_AddressAndPortDependentFiltering 地址和端口依赖过滤，认为是 地址端口受限锥形
   4、 NAT_BEHAVIOR_AddressDependentMapping
	  和3一样
   5、NAT_BEHAVIOR_AddressAndPortDependentMapping  认为是对称型
*/

namespace ServiceNatDetection
{
NatBehavior get_nat_behavior(std::string& nat_ip, const std::string& stun_server, uint16_t stun_port);
NatFiltering get_nat_filtering(std::string& nat_ip, const std::string& stun_server, uint16_t stun_port);
NAT_TYPE get_nat_type(NatBehavior natBehavior, NatFiltering natFiltering);
};
