# Path: ogn/parser/utils.py
# def parseAngle(dddmmhht):
#     return float(dddmmhht[:3]) + float(dddmmhht[3:]) / 60
# 
# def createTimestamp(time_string, reference_timestamp):
#     if time_string[-1] == "z":
#         dd = int(time_string[0:2])
#         hh = int(time_string[2:4])
#         mm = int(time_string[4:6])
# 
#         result = datetime(reference_timestamp.year,
#                           reference_timestamp.month,
#                           dd,
#                           hh, mm, 0,
#                           tzinfo=timezone.utc if reference_timestamp.tzinfo is not None else None)
# 
#         # correct wrong month
#         if result > reference_timestamp + timedelta(days=14):
#             result = (result.replace(day=1) - timedelta(days=14)).replace(day=result.day)
#         elif result < reference_timestamp - timedelta(days=14):
#             result = (result.replace(day=28) + timedelta(days=14)).replace(day=result.day)
#     else:
#         hh = int(time_string[0:2])
#         mm = int(time_string[2:4])
#         ss = int(time_string[4:6])
# 
#         result = datetime(reference_timestamp.year,
#                           reference_timestamp.month,
#                           reference_timestamp.day,
#                           hh, mm, ss,
#                           tzinfo=timezone.utc if reference_timestamp.tzinfo is not None else None)
# 
#         if result > reference_timestamp + timedelta(hours=12):
#             # shift timestamp to previous day
#             result -= timedelta(days=1)
#         elif result < reference_timestamp - timedelta(hours=12):
#             # shift timestamp to next day
#             result += timedelta(days=1)
# 
#     return result
# 
# class CheapRuler():
#     """Extreme fast distance calculating for distances below 500km."""
# 
#     def __init__(self, lat):
#         c = math.cos(lat * MATH_PI / 180)
#         c2 = 2 * c * c - 1
#         c3 = 2 * c * c2 - c
#         c4 = 2 * c * c3 - c2
#         c5 = 2 * c * c4 - c3
# 
#         self.kx = 1000 * (111.41513 * c - 0.09455 * c3 + 0.00012 * c5)  # longitude correction
#         self.ky = 1000 * (111.13209 - 0.56605 * c2 + 0.0012 * c4)       # latitude correction
# 
#     def distance(self, a, b):
#         """Distance between point a and b. A point is a tuple(lon,lat)."""
# 
#         dx = (a[0] - b[0]) * self.kx
#         dy = (a[1] - b[1]) * self.ky
#         return math.sqrt(dx * dx + dy * dy)
# 
#     def bearing(self, a, b):
#         """Returns the bearing from point a to point b."""
# 
#         dx = (b[0] - a[0]) * self.kx
#         dy = (b[1] - a[1]) * self.ky
#         if dx == 0 and dy == 0:
#             return 0
#         result = math.atan2(-dy, dx) * 180 / MATH_PI + 90
#         return result if result >= 0 else result + 360
# 
# def normalized_quality(distance, signal_quality):
#     """Signal quality normalized to 10km."""
# 
#     return signal_quality + 20.0 * math.log10(distance / 10000.0) if distance > 0 else None


import unittest
from datetime import datetime, timezone
from ogn.parser.utils import parseAngle, createTimestamp, CheapRuler, normalized_quality
        ]

        self.proceed_test_data(test_data)

    def test_createTimestamp_tzinfo(self):
        test_data = [
            ('000001h', datetime(2020, 9, 10, 0, 0, 1, tzinfo=timezone.utc), (datetime(2020, 9, 10, 0, 0, 1, tzinfo=timezone.utc)))
        ]

        self.proceed_test_data(test_data)

    def test_cheap_ruler_distance(self):
        koenigsdf = (11.465353, 47.829825)
        hochkoenig = (13.062405, 47.420516)

        cheap_ruler = CheapRuler((koenigsdf[1] + hochkoenig[1]) / 2)
        distance = cheap_ruler.distance(koenigsdf, hochkoenig)
        self.assertAlmostEqual(distance, 128381.47612138899)

    def test_cheap_ruler_bearing(self):
        koenigsdf = (11.465353, 47.829825)
        hochkoenig = (13.062405, 47.420516)

        cheap_ruler = CheapRuler((koenigsdf[1] + hochkoenig[1]) / 2)
        bearing = cheap_ruler.bearing(koenigsdf, hochkoenig)
        self.assertAlmostEqual(bearing, 110.761300063515)

    def test_normalized_quality(self):
        self.assertAlmostEqual(normalized_quality(10000, 1), 1)
        self.assertAlmostEqual(normalized_quality(20000, 10), 16.020599913279625)

# Path: ogn/parser/utils.py
# def parseAngle(dddmmhht):
#     return float(dddmmhht[:3]) + float(dddmmhht[3:]) / 60
# 
# def createTimestamp(time_string, reference_timestamp):
#     if time_string[-1] == "z":
#         dd = int(time_string[0:2])
#         hh = int(time_string[2:4])
#         mm = int(time_string[4:6])
# 
#         result = datetime(reference_timestamp.year,
#                           reference_timestamp.month,
#                           dd,
#                           hh, mm, 0,
#                           tzinfo=timezone.utc if reference_timestamp.tzinfo is not None else None)
# 
#         # correct wrong month
#         if result > reference_timestamp + timedelta(days=14):
#             result = (result.replace(day=1) - timedelta(days=14)).replace(day=result.day)
#         elif result < reference_timestamp - timedelta(days=14):
#             result = (result.replace(day=28) + timedelta(days=14)).replace(day=result.day)
#     else:
#         hh = int(time_string[0:2])
#         mm = int(time_string[2:4])
#         ss = int(time_string[4:6])
# 
#         result = datetime(reference_timestamp.year,
#                           reference_timestamp.month,
#                           reference_timestamp.day,
#                           hh, mm, ss,
#                           tzinfo=timezone.utc if reference_timestamp.tzinfo is not None else None)
# 
#         if result > reference_timestamp + timedelta(hours=12):
#             # shift timestamp to previous day
#             result -= timedelta(days=1)
#         elif result < reference_timestamp - timedelta(hours=12):
#             # shift timestamp to next day
#             result += timedelta(days=1)
# 
#     return result
# 
# class CheapRuler():
#     """Extreme fast distance calculating for distances below 500km."""
# 
#     def __init__(self, lat):
#         c = math.cos(lat * MATH_PI / 180)
#         c2 = 2 * c * c - 1
#         c3 = 2 * c * c2 - c
#         c4 = 2 * c * c3 - c2
#         c5 = 2 * c * c4 - c3
# 
#         self.kx = 1000 * (111.41513 * c - 0.09455 * c3 + 0.00012 * c5)  # longitude correction
#         self.ky = 1000 * (111.13209 - 0.56605 * c2 + 0.0012 * c4)       # latitude correction
# 
#     def distance(self, a, b):
#         """Distance between point a and b. A point is a tuple(lon,lat)."""
# 
#         dx = (a[0] - b[0]) * self.kx
#         dy = (a[1] - b[1]) * self.ky
#         return math.sqrt(dx * dx + dy * dy)
# 
#     def bearing(self, a, b):
#         """Returns the bearing from point a to point b."""
# 
#         dx = (b[0] - a[0]) * self.kx
#         dy = (b[1] - a[1]) * self.ky
#         if dx == 0 and dy == 0:
#             return 0
#         result = math.atan2(-dy, dx) * 180 / MATH_PI + 90
#         return result if result >= 0 else result + 360
# 
# def normalized_quality(distance, signal_quality):
#     """Signal quality normalized to 10km."""
# 
#     return signal_quality + 20.0 * math.log10(distance / 10000.0) if distance > 0 else None


# Path: tests/parser/test_utils.py
import unittest
from datetime import datetime, timezone
from ogn.parser.utils import parseAngle, createTimestamp, CheapRuler, normalized_quality

        ]

        self.proceed_test_data(test_data)

    def test_createTimestamp_tzinfo(self):
        test_data = [
            ('000001h', datetime(2020, 9, 10, 0, 0, 1, tzinfo=timezone.utc), (datetime(2020, 9, 10, 0, 0, 1, tzinfo=timezone.utc)))
        ]

        self.proceed_test_data(test_data)

    def test_cheap_ruler_distance(self):
        koenigsdf = (11.465353, 47.829825)
        hochkoenig = (13.062405, 47.420516)

        cheap_ruler = CheapRuler((koenigsdf[1] + hochkoenig[1]) / 2)
        distance = cheap_ruler.distance(koenigsdf, hochkoenig)
        self.assertAlmostEqual(distance, 128381.47612138899)

    def test_cheap_ruler_bearing(self):
        koenigsdf = (11.465353, 47.829825)
        hochkoenig = (13.062405, 47.420516)

        cheap_ruler = CheapRuler((koenigsdf[1] + hochkoenig[1]) / 2)
        bearing = cheap_ruler.bearing(koenigsdf, hochkoenig)
        self.assertAlmostEqual(bearing, 110.761300063515)

    def test_normalized_quality(self):
        self.assertAlmostEqual(normalized_quality(10000, 1), 1)
        self.assertAlmostEqual(normalized_quality(20000, 10), 16.020599913279625)

        self.assertAlmostEqual(normalized_quality(5000, 5), -1.0205999132796242)