# Path: ogn/parser/utils.py
# FPM_TO_MS = FEETS_TO_METER / 60     # ratio fpm to m/s
# 
# Path: ogn/parser/pattern.py
# PATTERN_SAFESKY_POSITION_COMMENT = re.compile(r"""
#     id(?P<details>[\dA-F]{2})(?P<address>[\dA-F]{6}?)\s?
#     (?:(?P<climb_rate>[+-]\d+?)fpm\s)?
#     (?:gps(?P<gps_quality>(?P<gps_quality_horizontal>(\d+))x(?P<gps_quality_vertical>(\d+)))?)?
# """, re.VERBOSE | re.MULTILINE)
# 
# Path: ogn/parser/aprs_comment/base.py
# class BaseParser():
#     def __init__(self):
#         self.beacon_type = 'unknown'
# 
#     def parse(self, aprs_comment, aprs_type):
#         if aprs_type.startswith('position'):
#             data = self.parse_position(aprs_comment)
#         elif aprs_type.startswith('status'):
#             data = self.parse_status(aprs_comment)
#         else:
#             raise ValueError("aprs_type {} unknown".format(aprs_type))
#         data.update({'beacon_type': self.beacon_type})
#         return data
# 
#     def parse_position(self, aprs_comment):
#         raise NotImplementedError("Position parser for parser '{}' not yet implemented".format(self.beacon_type))
# 
#     def parse_status(self, aprs_comment):
#         raise NotImplementedError("Status parser for parser '{}' not yet implemented".format(self.beacon_type))


from ogn.parser.utils import FPM_TO_MS
from ogn.parser.pattern import PATTERN_SAFESKY_POSITION_COMMENT
from .base import BaseParser



class SafeskyParser(BaseParser):
    def __init__(self):
        self.beacon_type = 'safesky'
        self.position_pattern = PATTERN_SAFESKY_POSITION_COMMENT

    def parse_position(self, aprs_comment):
        match = self.position_pattern.match(aprs_comment)
        result = dict()
        if match.group('details'):
            result.update({
                'address_type': int(match.group('details'), 16) & 0b00000011,
                'aircraft_type': (int(match.group('details'), 16) & 0b00111100) >> 2,
                'no-tracking': (int(match.group('details'), 16) & 0b01000000) >> 6 == 1,
                'stealth': (int(match.group('details'), 16) & 0b10000000) >> 7 == 1,
                'address': match.group('address'),
            })
        result.update(
            {'climb_rate': int(match.group('climb_rate')) * FPM_TO_MS if match.group('climb_rate') else None})
        if match.group('gps_quality'):
            result.update({

# Path: ogn/parser/utils.py
# FPM_TO_MS = FEETS_TO_METER / 60     # ratio fpm to m/s
# 
# Path: ogn/parser/pattern.py
# PATTERN_SAFESKY_POSITION_COMMENT = re.compile(r"""
#     id(?P<details>[\dA-F]{2})(?P<address>[\dA-F]{6}?)\s?
#     (?:(?P<climb_rate>[+-]\d+?)fpm\s)?
#     (?:gps(?P<gps_quality>(?P<gps_quality_horizontal>(\d+))x(?P<gps_quality_vertical>(\d+)))?)?
# """, re.VERBOSE | re.MULTILINE)
# 
# Path: ogn/parser/aprs_comment/base.py
# class BaseParser():
#     def __init__(self):
#         self.beacon_type = 'unknown'
# 
#     def parse(self, aprs_comment, aprs_type):
#         if aprs_type.startswith('position'):
#             data = self.parse_position(aprs_comment)
#         elif aprs_type.startswith('status'):
#             data = self.parse_status(aprs_comment)
#         else:
#             raise ValueError("aprs_type {} unknown".format(aprs_type))
#         data.update({'beacon_type': self.beacon_type})
#         return data
# 
#     def parse_position(self, aprs_comment):
#         raise NotImplementedError("Position parser for parser '{}' not yet implemented".format(self.beacon_type))
# 
#     def parse_status(self, aprs_comment):
#         raise NotImplementedError("Status parser for parser '{}' not yet implemented".format(self.beacon_type))


# Path: ogn/parser/aprs_comment/safesky_parser.py
from ogn.parser.utils import FPM_TO_MS
from ogn.parser.pattern import PATTERN_SAFESKY_POSITION_COMMENT
from .base import BaseParser




class SafeskyParser(BaseParser):
    def __init__(self):
        self.beacon_type = 'safesky'
        self.position_pattern = PATTERN_SAFESKY_POSITION_COMMENT

    def parse_position(self, aprs_comment):
        match = self.position_pattern.match(aprs_comment)
        result = dict()
        if match.group('details'):
            result.update({
                'address_type': int(match.group('details'), 16) & 0b00000011,
                'aircraft_type': (int(match.group('details'), 16) & 0b00111100) >> 2,
                'no-tracking': (int(match.group('details'), 16) & 0b01000000) >> 6 == 1,
                'stealth': (int(match.group('details'), 16) & 0b10000000) >> 7 == 1,
                'address': match.group('address'),
            })
        result.update(
            {'climb_rate': int(match.group('climb_rate')) * FPM_TO_MS if match.group('climb_rate') else None})
        if match.group('gps_quality'):
            result.update({

                'gps_quality': {