# -*- coding: utf-8 -*-
import scrapy
import time
import json
import redis
from AirplaneSpiders.items import AirPlaneLiveItem
from scrapy.http.cookies import CookieJar

# 高敏飞机历史轨迹下载--数据源：https://globe.adsbexchange.com/#
class AirplaneLiveSensitive2Spider(scrapy.Spider):
    name = 'adsbexchange_airplane_live_sensitive'
    allowed_domains = ['adsbexchange.com']
    start_urls = ['http://adsbexchange.com/']
    # adsbexchange_api = 'https://globe.adsbexchange.com/data/traces/8e/trace_recent_%s.json'

    custom_settings = {
        'PROTO_MODULE_PATH': 'AirplaneSpiders.proto.Plane_pb2',
        'PROTO_CLASS_NAME': 'FligthTrackpointInfoSets',
        'PROTO_FIELD_NAME': 'FligthTrackpointInfo',
        'PROTO_SAVE_FILE_PATH': r'/usr/local/spider_data',
        'PROTO_SAVE_FILE_NAME': r'track_data_plane_',
        'ITEM_PIPELINES': {
            'AirplaneSpiders.pipelines.ProtobufSavePipeline': 300,
            'AirplaneSpiders.pipelines.FlightIdSavePipeline': 301
        }
    }

    def __init__(self, params=None, *args, **kwargs):
        super(AirplaneLiveSensitive2Spider, self).__init__(*args, **kwargs)
        json_params = json.loads(params)
        if 'job_id' in json_params:
            self.job_id = json_params['job_id']

    def start_requests(self):
        self.redis_client = redis.Redis(host=self.settings['REDIS_HOST'], port=self.settings['REDIS_PORT'],
                                        password=self.settings['REDIS_PWD'], decode_responses=True)
        self.reg_icao_list = json.loads(str(self.redis_client.hgetall('AirplaneSpiders:reg_icao')).replace('\'', '"'))
        self.icao_flightId_list = json.loads(
            str(self.redis_client.hgetall('AirplaneSpiders:adsbexchange_icao_flightid')).replace('\'', '"'))
        self.redis_client.close()

        yield scrapy.Request(url='https://globe.adsbexchange.com', callback=self.parseCookie)

    def parseCookie(self, response):
        # 提取cookie
        cookie_dict = {}
        cookie_jar = CookieJar()
        cookie_jar.extract_cookies(response, response.request)
        for k, v in cookie_jar._cookies.items():
            for i, j in v.items():
                for m, n in j.items():
                    cookie_dict[m] = n.value

        for reg in self.reg_icao_list:
            # 飞机注册号
            reg = str(reg)
            # 飞机的 24 位 ICAO 标识符
            icao = str(self.reg_icao_list[reg])
            headers_dict = {
                'Accept': 'application/json, text/javascript, */*; q=0.01',
                # 'Accept-Language': 'zh-CN,zh;q=0.9',
                # 'Accept-Encoding': 'gzip, deflate, br',
                'Host': 'globe.adsbexchange.com',
                'Cache-Control': 'no-cache',
                'Pragma': 'no-cache'
            }
            headers_dict['Referer'] = 'https://globe.adsbexchange.com/?icao=%s' % str(icao).lower()

            if icao in self.icao_flightId_list and self.icao_flightId_list[icao] != '':
                flight_id = self.icao_flightId_list[icao]
            else:
                flight_id = str(icao) + '-' + str(int(time.time() * 1000))
                self.redis_client = redis.Redis(host=self.settings['REDIS_HOST'], port=self.settings['REDIS_PORT'],
                                                password=self.settings['REDIS_PWD'], decode_responses=True)
                self.redis_client.hset('AirplaneSpiders:adsbexchange_icao_flightid', icao, flight_id)
                self.redis_client.close()

            yield scrapy.Request(url='https://globe.adsbexchange.com/data/traces/%s/trace_recent_%s.json' % (
                str(icao)[-2:].lower(), str(icao).lower()), headers=headers_dict, cookies=cookie_dict,
                                 meta={'icao': icao, 'reg': reg, 'flightid': flight_id}, callback=self.parseLiveData)

    def parseLiveData(self, response):
        try:
            icao = response.meta['icao']
            reg = response.meta['reg']
            flightid = response.meta['flightid']
            if response.status == 200:
                data = json.loads(response.text)
                timestamp = int(float(data['timestamp']) * 1000)
                trace_list = data['trace']

                if trace_list[-1][3] != 'ground':
                    item = AirPlaneLiveItem()
                    item['FlightID'] = flightid
                    item['PlaneREG'] = reg
                    if trace_list[-1][4] is not None:
                        item['Speed'] = str(trace_list[-1][4])
                    if trace_list[-1][5] is not None:
                        item['Angle'] = str(trace_list[-1][5])
                    item['LastTime'] = str(timestamp + int(float(trace_list[-1][0] * 1000)))
                    item['UpdateTime'] = str(int(time.time() * 1000))
                    if trace_list[-1][1] is not None:
                        item['Latitude'] = str(trace_list[-1][1])
                    if trace_list[-1][2] is not None:
                        item['Longitude'] = str(trace_list[-1][2])
                    if trace_list[-1][3] is not None:
                        item['Height'] = int(trace_list[-1][3]) * 0.3048
                    item['source'] = 'adsbexchange'
                    yield item
                else:
                    if trace_list[-2][3] != 'ground':
                        item = AirPlaneLiveItem()
                        item['FlightID'] = flightid
                        item['PlaneREG'] = reg
                        item['Speed'] = str(trace_list[-1][4])
                        item['Angle'] = str(trace_list[-1][5])
                        item['LastTime'] = str(timestamp + float(trace_list[-1][0] * 1000))
                        item['UpdateTime'] = str(int(time.time() * 1000))
                        item['Latitude'] = str(trace_list[-1][1])
                        item['Longitude'] = str(trace_list[-1][2])
                        item['Height'] = 0
                        # item['vs'] = str(trace_list[-1][7]) # ft/min
                        item['source'] = 'adsbexchange'

                        flightid = str(icao) + '-' + str(int(time.time() * 1000))
                        self.redis_client = redis.Redis(host=self.settings['REDIS_HOST'],
                                                        port=self.settings['REDIS_PORT'],
                                                        password=self.settings['REDIS_PWD'], decode_responses=True)
                        self.redis_client.hset('AirplaneSpiders:adsbexchange_icao_flightid', icao, flightid)
                        self.redis_client.close()

                        yield item
            else:
                self.logger.warning('未查询到飞机的实时信息--注册号：%s，ICAO：%s' % (reg, icao))
        except Exception as e:
            self.logger.error("来自数据源 adsbexchange 的飞机实时信息解析错误，原因是：", e)
