#! /usr/bin/env python3
# vim:fenc=utf-8
#
# Copyright © 2024 fred <github-fred@hidzz.com>
#
# Distributed under terms of the BSD 3-Clause license.

import re
from collections.abc import Mapping

# MacLoggerDX will accept anything for mode. This mapping for the
# modes accepted by lotw.
_MODEMAP = {
  'CLOVER': 'CLOVER',
  'AM': 'AM',
  'AMTOR': 'AMTOR',
  'AMTORFEC': 'AMTOR',
  'ARDOP': 'ARDOP',
  'ASCI': 'RTTY',
  'ATV': 'ATV',
  'BPSK125': 'PSK125',
  'BPSK31': 'PSK31',
  'BPSK63': 'PSK63',
  'C4FM': 'C4FM',
  'CHIP': 'CHIP',
  'CHIP128': 'CHIP',
  'CHIP64': 'CHIP',
  'CONTESTI': 'CONTESTI',
  'CONTESTI4125': 'CONTESTI',
  'CONTESTI4250': 'CONTESTI',
  'CONTESTI4500': 'CONTESTI',
  'CONTESTI8125': 'CONTESTI',
  'CONTESTI8250': 'CONTESTI',
  'CONTESTI8500': 'CONTESTI',
  'CONTESTI16500': 'CONTESTI',
  'CW': 'CW',
  'DATA': 'DATA',
  'DIGITALVOICE': 'DIGITALVOICE',
  'DOMINO': 'DOMINO',
  'DOMINOEX': 'DOMINO',
  'DOMINOF': 'DOMINO',
  'DSTAR': 'DSTAR',
  'FAX': 'FAX',
  'FM': 'FM',
  'FMHELL': 'HELL',
  'FSK31': 'FSK31',
  'FSK441': 'FSK441',
  'FSKHELL': 'HELL',
  'FSQCALL': 'DATA',
  'FT8': 'FT8',
  'GTOR': 'GTOR',
  'HELL': 'HELL',
  'HELL80': 'HELL',
  'HFSK': 'HFSK',
  'ISCAT': 'ISCAT',
  'ISCATA': 'ISCAT',
  'ISCATB': 'ISCAT',
  'JS8': 'DATA',
  'JT4': 'JT4',
  'JT4A': 'JT4',
  'JT4B': 'JT4',
  'JT4C': 'JT4',
  'JT4D': 'JT4',
  'JT4E': 'JT4',
  'JT4F': 'JT4',
  'JT4G': 'JT4',
  'JT65': 'JT65',
  'JT65A': 'JT65',
  'JT65B': 'JT65',
  'JT65B2': 'JT65',
  'JT65C': 'JT65',
  'JT65C2': 'JT65',
  'JT6M': 'JT6M',
  'JT9': 'JT9',
  'JT91': 'JT9',
  'JT910': 'JT9',
  'JT92': 'JT9',
  'JT930': 'JT9',
  'JT95': 'JT9',
  'JT9A': 'JT9',
  'JT9B': 'JT9',
  'JT9C': 'JT9',
  'JT9D': 'JT9',
  'JT9E': 'JT9',
  'JT9EFAST': 'JT9',
  'JT9F': 'JT9',
  'JT9FFAST': 'JT9',
  'JT9G': 'JT9',
  'JT9GFAST': 'JT9',
  'JT9H': 'JT9',
  'JT9HFAST': 'JT9',
  'LSB': 'SSB',
  'MFSK11': 'MFSK11',
  'MFSK128': 'DATA',
  'MFSK16': 'MFSK16',
  'MFSK22': 'DATA',
  'MFSK31': 'DATA',
  'MFSK32': 'DATA',
  'MFSK4': 'DATA',
  'MFSK64': 'DATA',
  'MFSK8': 'MFSK8',
  'MSK144': 'MSK144',
  'MT63': 'MT63',
  'OLIVIA': 'OLIVIA',
  'OLIVIA161000': 'OLIVIA',
  'OLIVIA16500': 'OLIVIA',
  'OLIVIA321000': 'OLIVIA',
  'OLIVIA4125': 'OLIVIA',
  'OLIVIA4250': 'OLIVIA',
  'OLIVIA8250': 'OLIVIA',
  'OLIVIA8500': 'OLIVIA',
  'OPERA': 'OPERA',
  'OPERABEACON': 'OPERA',
  'OPERAQSO': 'OPERA',
  'PAC2': 'PACTOR',
  'PAC3': 'PACTOR',
  'PAC4': 'PACTOR',
  'PACKET': 'PACKET',
  'PACTOR': 'PACTOR',
  'PAX': 'PAX',
  'PAX2': 'PAX',
  'PCW': 'CW',
  'PSK10': 'PSK10',
  'PSK1000': 'DATA',
  'PSK125': 'PSK125',
  'PSK250': 'DATA',
  'PSK2K': 'PSK2K',
  'PSK31': 'PSK31',
  'PSK500': 'DATA',
  'PSK63': 'PSK63',
  'PSK63F': 'PSK63F',
  'PSKAM10': 'PSKAM',
  'PSKAM31': 'PSKAM',
  'PSKAM50': 'PSKAM',
  'PSKFEC31': 'PSKFEC31',
  'PSKHELL': 'HELL',
  'Q15': 'Q15',
  'QPSK125': 'PSK125',
  'QPSK250': 'DATA',
  'QPSK31': 'PSK31',
  'QPSK500': 'DATA',
  'QPSK63': 'PSK63',
  'QRA64': 'QRA64',
  'QRA64A': 'QRA64',
  'QRA64B': 'QRA64',
  'QRA64C': 'QRA64',
  'QRA64D': 'QRA64',
  'QRA64E': 'QRA64',
  'ROS': 'ROS',
  'ROSEME': 'ROS',
  'ROSHF': 'ROS',
  'ROSMF': 'ROS',
  'RTTY': 'RTTY',
  'RTTYM': 'RTTYM',
  'SIM31': 'DATA',
  'SSB': 'SSB',
  'SSTV': 'SSTV',
  'T10': 'T10',
  'THOR': 'THOR',
  'THOR4': 'THOR',
  'THOR5': 'THOR',
  'THOR8': 'THOR',
  'THOR11': 'THOR',
  'THOR16': 'THOR',
  'THRBX': 'THROB',
  'THROB': 'THROB',
  'USB': 'SSB',
  'VOI': 'VOI',
  'WINMOR': 'WINMOR',
  'WSPR': 'WSPR',
}


class MODEMap(Mapping):
  def __init__(self):
    self._clean = re.compile('[^A-Z0-9]+')
    self._map = _MODEMAP

  def clean(self, value):
    return self._clean.sub('', value.upper())

  def __getitem__(self, key, default='DATA'):
    key = self.clean(key)
    if key in self._map:
      return self._map[self.clean(key)]
    return default

  def __iter__(self):
    return iter(self._map)

  def __len__(self):
    return len(self._map)
