import time
from Ansjer.config import LOGGER
from django.http import HttpResponse
from django.utils.decorators import method_decorator
from django.views import View

from django.views.decorators.csrf import csrf_exempt
from Model.models import CountryModel, RegionModel, P2PIpModel, DeviceDomainModel, DeviceDomainRegionModel, IPAddr
from Object.ResponseObject import ResponseObject
from Service.CommonService import CommonService
from Object.IPWeatherObject import IPQuery


class ConfirmRegion(View):
    # 设备根据ip获取域名
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(ConfirmRegion, self).dispatch(*args, **kwargs)

    @staticmethod
    def get(request, *args, **kwargs):
        response = ResponseObject()
        request.encoding = 'utf-8'
        try:
            ip = CommonService.get_ip_address(request)
            device_domain_qs = DeviceDomainModel.objects.filter(ip=ip)

            # 获取国家编码
            ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False).values('country_code', 'region')
            if ip_addr_qs.exists():
                country_code = ip_addr_qs[0]['country_code']
                region = ip_addr_qs[0]['region']
            else:
                ip_qs = IPQuery(ip)
                country_code = ip_qs.country_id
                region = ip_qs.region

            if country_code:
                # 港澳台返回美洲域名
                if country_code == 'CN' and region in ['香港', '澳门', '台湾']:
                    api, push_api, region_id, push_region = get_default_api()
                else:
                    country_qs = CountryModel.objects.filter(country_code=country_code).\
                        values('region__api', 'region__push_api')
                    if country_qs.exists():
                        api = country_qs[0]['region__api']
                        push_api = country_qs[0]['region__push_api']

                        if not device_domain_qs.exists():
                            DeviceDomainModel.objects.create(ip=ip, country_name=country_code, api=api)
                    else:
                        api, push_api, region_id, push_region = get_default_api()

                    push_region = get_push_region(api)
                    res = {
                        'request_api_url': api,
                        'push_api_url': push_api,
                        'push_region': push_region
                    }
                    return response.json(0, res)

            # 不存在则返回美洲域名
            api, push_api, region_id, push_region = get_default_api()
            if not device_domain_qs.exists():
                DeviceDomainModel.objects.create(ip=ip, country_name='NA', api=api)

            res = {
                'request_api_url': api,
                'push_api_url': push_api,
                'push_region': push_region
            }
            return response.json(0, res)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))


class ConfirmRegionV2(View):
    # 设备根据ip获取域名V2接口
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(ConfirmRegionV2, self).dispatch(*args, **kwargs)

    @staticmethod
    def get(request, *args, **kwargs):
        response = ResponseObject()

        # 获取ip
        request.encoding = 'utf-8'
        ip = CommonService.get_ip_address(request)

        serial_number = request.GET.get('serial_number', None)
        if not serial_number:
            return response.json(444)
        try:
            data_dict = {'ip': ip}
            device_domain_region_qs = DeviceDomainRegionModel.objects.filter(serial_number=serial_number)

            # 获取国家编码
            ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False).values('country_code', 'region')
            if ip_addr_qs.exists():
                country_code = ip_addr_qs[0]['country_code']
                region = ip_addr_qs[0]['region']
            else:
                ip_qs = IPQuery(ip)
                country_code = ip_qs.country_id
                region = ip_qs.region

            if country_code:
                data_dict['country_code'] = country_code
                # 港澳台返回美洲域名
                if country_code == 'CN' and region in ['香港', '澳门', '台湾']:
                    api, push_api, region_id, push_region = get_default_api()
                else:
                    country_qs = CountryModel.objects.filter(country_code=country_code).\
                        values('region__api', 'region__push_api', 'region__id')
                    if country_qs.exists():
                        api = country_qs[0]['region__api']
                        push_api = country_qs[0]['region__push_api']
                        region_id = country_qs[0]['region__id']
                        push_region = get_push_region(api)
                    else:
                        # 返回美洲域名
                        data_dict['country_code'] = 'N/A'
                        api, push_api, region_id, push_region = get_default_api()
            else:
                # 返回美洲域名
                data_dict['country_code'] = 'N/A'
                api, push_api, region_id, push_region = get_default_api()

            # 更新或创建设备域名数据
            data_dict['region_id'] = region_id
            if device_domain_region_qs.exists():
                device_domain_region_qs.update(**data_dict)
            else:
                data_dict['serial_number'] = serial_number
                device_domain_region_qs.create(**data_dict)

            LOGGER.info('获取域名V2接口信息:{},{}'.format(serial_number, data_dict))

            # 响应数据
            res = {
                'request_api_url': api,
                'push_api_url': push_api,
                'region_id': region_id,
                'push_region': push_region
            }
            return response.json(0, res)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))


def get_default_api():
    # 获取默认域名(美洲服域名)
    region_qs = RegionModel.objects.filter(continent_code='NA').values('api', 'push_api', 'id')
    api = region_qs[0]['api']
    push_api = region_qs[0]['push_api']
    region_id = region_qs[0]['id']
    push_region = 1  # 推送图片S3存储地区,1：国外, 2:国内
    return api, push_api, region_id, push_region


def get_push_region(api):
    """
    根据域名获取推送图片S3存储地区
    @param api:
    @return: push_region
    """
    push_region = 2 if '.cn' in api else 1
    return push_region


class Device_Region(object):

    def get_device_region(self, ip):
        ipInfo = CommonService.getIpIpInfo(ip, "CN")
        # 暂时测试国外
        if ipInfo['country_code']:
            device_request_url = CountryModel.objects.filter(country_code=ipInfo['country_code']).\
                values("region__api", "region__id")
            if device_request_url.exists():
                return device_request_url[0]['region__id']
        # 不存在默认返回美洲地区api
        api = RegionModel.objects.filter(continent_code='NA').values("id")
        return api[0]['id']


# 根据p2p的ip统计设备所在地区
class StatisticsIpRegion(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(StatisticsIpRegion, self).dispatch(*args, **kwargs)

    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        return self.ipRegion(request.GET)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        return self.ipRegion(request.POST)

    def ipRegion(self, request_dict):
        response = ResponseObject()
        ip = request_dict.get('ip', None)
        uid = request_dict.get('uid', None)
        p2p_request_times = int(request_dict.get('p2p_request_times', 0))
        relay_request_times = int(request_dict.get('relay_request_times', 0))

        if not all([ip, uid]) or (not p2p_request_times and not relay_request_times):
            return response.json(444)

        try:
            now_time = int(time.time())
            p2p_ip_qs = P2PIpModel.objects.filter(uid=uid).values('p2p_request_times', 'relay_request_times')
            if p2p_ip_qs.exists():
                # 已存在数据,更新p2p请求次数和relay请求次数
                p2p_request_times = p2p_ip_qs[0]['p2p_request_times'] + p2p_request_times
                relay_request_times = p2p_ip_qs[0]['relay_request_times'] + relay_request_times
                p2p_ip_qs.update(p2p_request_times=p2p_request_times, relay_request_times=relay_request_times,
                                 update_time=now_time)
            else:
                # 根据ip确定位置信息
                ip_info = CommonService.getIpIpInfo(ip, 'CN')
                # 获取大洲,国家,地区,城市
                continent_code = ip_info['continent_code']
                country_name = ip_info['country_name']
                if continent_code == 'AP' and country_name != 'CN':
                    # 如果大洲代码为'AP',国家不为'CN',为亚洲
                    continent_code = 'AS'
                continent_name = RegionModel.objects.filter(continent_code=continent_code).values('name')[0]['name']
                region_name = ip_info['region_name']
                city_name = ip_info['city_name']
                P2PIpModel.objects.create(uid=uid, ip=ip, continent_name=continent_name, country_name=country_name,
                                          region_name=region_name, city_name=city_name,
                                          p2p_request_times=p2p_request_times, relay_request_times=relay_request_times,
                                          add_time=now_time, update_time=now_time)
            return response.json(0)
        except Exception as e:
            print(e)
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))


def confirm_country_with_ip(request):
    '''
    根据ip统计设备所在国家的程序,
    ip.txt放在ASJServer目录下
    '''
    response = ResponseObject()
    try:
        with open('country.txt', 'w', encoding='utf-8') as wf:
            with open('ip.txt', 'r') as rf:
                for ip in rf.readlines():
                    if not ip or ip == '\n':
                        country = 'N/A'
                    else:
                        if '\n' in ip:
                            ip = ip[:-1]
                        ipInfo = CommonService.getIpIpInfo(ip, "CN")
                        country = ipInfo['country_name'] if ipInfo['country_name'] else 'N/A'
                    wf.write(country+'\n')
        return response.json(0)
    except Exception as e:
        print(e)
        return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))


def confirm_region_with_ip(request):
    """
    app下载链接确认地区
    @param request:
    @return:
    """
    try:
        request.encoding = 'utf-8'
        ip = CommonService.get_ip_address(request)

        # 获取地区和国家信息
        ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False).values('region', 'country_code')
        if ip_addr_qs.exists():
            region = ip_addr_qs[0]['region']
            country_code = ip_addr_qs[0]['country_code']
        else:
            ip_qs = IPQuery(ip)
            region = ip_qs.region
            country_code = ip_qs.country_id

        # 海外返回200状态码,国内403
        if country_code != 'CN':
            return HttpResponse()
        elif region in ['香港', '澳门', '台湾']:
            return HttpResponse()
        return HttpResponse(status=403)
    except Exception as e:
        return HttpResponse(status=500,
                            content='error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
