# coding=utf-8
import logging

service_cls = [
    "positioning",
    "networking",
    "rendering",
    "capturing",
    "object transfer",
    "audio",
    "telephony",
    "information"
]

major_cls = [
    "miscellaneous",
    "computer",
    "phone",
    "access point",
    "audio/video",
    "peripheral",
    "imaging",
    "wearable",
    "toy",
    "uncategorized"
]

computer_minor_cls = [
    "uncategorized",
    "desktop",
    "server",
    "laptop",
    "handheld",
    "palm",
    "wearable"
]
computer_minor_cls_i18n = [
    # translators: device class
    _("uncategorized"),
    # translators: device class
    _("desktop"),
    # translators: device class
    _("server"),
    # translators: device class
    _("laptop"),
    # translators: device class
    _("handheld"),
    # translators: device class
    _("palm"),
    "wearable"
]

phone_minor_cls = [
    "uncategorized",
    "cellular",
    "cordless",
    "smart phone",
    "modem",
    "isdn"
]
phone_minor_cls_i18n = [
    # translators: device class
    _("uncategorized"),
    # translators: device class
    _("cellular"),
    # translators: device class
    _("cordless"),
    # translators: device class
    _("smart phone"),
    # translators: device class
    _("modem"),
    # translators: device class
    _("isdn")
]
access_point_minor_cls = [
    "fully",
    "1-17 percent",
    "17-33 percent",
    "33-50 percent",
    "50-67 percent",
    "67-83 percent",
    "83-99 percent",
    "not available"
]

audio_video_minor_cls = [
    "uncategorized",
    "headset",
    "handsfree",
    "unknown",
    "microphone",
    "loudspeaker",
    "headphones",
    "portable audio",
    "car audio",
    "set-top box",
    "hifi audio",
    "vcr",
    "video camera",
    "camcorder",
    "video monitor",
    "video display and loudspeaker",
    "video conferencing",
    "unknown",
    "gaming/toy"
]
audio_video_minor_cls_i18n = [
    "uncategorized",
    # translators: device class
    _("headset"),
    # translators: device class
    _("handsfree"),
    # translators: device class
    _("unknown"),
    # translators: device class
    _("microphone"),
    "loudspeaker",
    "headphones",
    "portable audio",
    "car audio",
    "set-top box",
    "hifi audio",
    "vcr",
    "video camera",
    "camcorder",
    "video monitor",
    "video display and loudspeaker",
    "video conferencing",
    "unknown",
    "gaming/toy"
]
peripheral_minor_cls = [
    "uncategorized",
    "keyboard",
    "pointing",
    "combo"
]
peripheral_minor_cls_i18n = [
    "uncategorized",
    # translators: device class
    _("keyboard"),
    # translators: device class
    _("pointing"),
    "combo"
]

imaging_minor_cls = [
    "display",
    "camera",
    "scanner",
    "printer"
]

wearable_minor_cls = [
    "wrist watch",
    "pager",
    "jacket",
    "helmet",
    "glasses"
]

toy_minor_cls = [
    "robot",
    "vehicle",
    "doll",
    "controller",
    "game"
]

gatt_appearance_categories = {
    0: ('Unknown', {0: 'Unknown'}),
    1: ('Phone', {0: 'Generic Phone'}),
    2: ('Computer', {0: 'Generic Computer'}),
    3: ('Watch', {0: 'Generic Watch',
                  1: 'Watch: Sports Watch'}),
    4: ('Clock', {0: 'Generic Clock'}),
    5: ('Display', {0: 'Generic Display'}),
    6: ('Remote Control', {0: 'Generic Remote Control'}),
    7: ('Eye-glasses', {0: 'Generic Eye-glasses'}),
    8: ('Tag', {0: 'Generic Tag'}),
    9: ('Keyring', {0: 'Generic Keyring'}),
    10: ('Media Player', {0: 'Generic Media Player'}),
    11: ('Barcode Scanner', {0: 'Generic Barcode Scanner'}),
    12: ('Thermometer', {0: 'Generic Thermometer',
                         1: 'Thermometer: Ear'}),
    13: ('Heart rate Sensor', {0: 'Generic Heart rate Sensor',
                               1: 'Heart Rate Sensor: Heart Rate Belt'}),
    14: ('Blood Pressure', {0: 'Generic Blood Pressure',
                            1: 'Blood Pressure: Arm',
                            2: 'Blood Pressure: Wrist'}),
    15: ('Human Interface Device (HID)', {0: 'Human Interface Device (HID)',
                                          1: 'Keyboard',
                                          2: 'Mouse',
                                          3: 'Joystick',
                                          4: 'Gamepad',
                                          5: 'Digitizer Tablet',
                                          6: 'Card Reader',
                                          7: 'Digital Pen',
                                          8: 'Barcode Scanner'}),
    16: ('Glucose Meter', {0: 'Generic Glucose Meter'}),
    17: ('Running Walking Sensor', {0: 'Generic: Running Walking Sensor',
                                    1: 'Running Walking Sensor: In-Shoe',
                                    2: 'Running Walking Sensor: On-Shoe',
                                    3: 'Running Walking Sensor: On-Hip'}),
    18: ('Cycling', {0: 'Generic: Cycling',
                     1: 'Cycling: Cycling Computer',
                     2: 'Cycling: Speed Sensor',
                     3: 'Cycling: Cadence Sensor',
                     4: 'Cycling: Power Sensor',
                     5: 'Cycling: Speed and Cadence Sensor'}),
    # 19 - 48 reserved
    49: ('Pulse Oximeter', {0: 'Generic: Pulse Oximeter',
                            1: 'Fingertip',
                            2: 'Wrist Worn'}),
    50: ('Weight Scale', {0: 'Generic: Weight Scale'}),
    51: ('Personal Mobility Device', {0: 'Generic Personal Mobility Device',
                                      1: 'Powered Wheelchair',
                                      2: 'Mobility Scooter'}),
    52: ('Continuous Glucose Monitor', {0: 'Generic Continuous Glucose Monitor'}),
    53: ('Insulin Pump', {0: 'Generic Insulin Pump',
                          1: 'Insulin Pump, durable pump',
                          4: 'Insulin Pump, patch pump',
                          8: 'Insulin Pen'}),
    54: ('Medication Delivery', {0: 'Generic Medication Delivery'}),
    # 55 - 80 reserved
    81: ('Outdoor Sports Activity', {0: 'Generic: Outdoor Sports Activity',
                                     1: 'Location Display Device',
                                     2: 'Location and Navigation Display Device',
                                     3: 'Location Pod',
                                     4: 'Location and Navigation Pod'})
}


def get_major_class(klass):
    index = (klass >> 8) & 0x1F

    if index > 8:
        return major_cls[9]

    return major_cls[index]


def get_minor_class(klass, i18n=False):
    if not klass:
        if i18n:
            return _("unknown")
        else:
            return "unknown"

    i = (klass >> 8) & 0x1F

    if i == 1:
        minor_index = (klass >> 2) & 0x3F
        if minor_index < len(computer_minor_cls):
            if i18n:
                return computer_minor_cls_i18n[minor_index]
            else:
                return computer_minor_cls[minor_index]
        else:
            return ""
    elif i == 2:
        minor_index = (klass >> 2) & 0x3F
        if minor_index < len(phone_minor_cls):
            if i18n:
                return phone_minor_cls_i18n[minor_index]
            else:
                return phone_minor_cls[minor_index]
        return ""
    elif i == 3:
        minor_index = (klass >> 5) & 0x07
        if minor_index < len(access_point_minor_cls):
            return access_point_minor_cls[minor_index]
        else:
            return ""
    elif i == 4:
        minor_index = (klass >> 2) & 0x3F
        if minor_index < len(audio_video_minor_cls):
            if i18n:
                return audio_video_minor_cls_i18n[minor_index]
            else:
                return audio_video_minor_cls[minor_index]
        else:
            return ""
    elif i == 5:
        minor_index = (klass >> 6) & 0x03
        if minor_index < len(peripheral_minor_cls):
            if i18n:
                return peripheral_minor_cls_i18n[minor_index]
            else:
                return peripheral_minor_cls[minor_index]
        else:
            return ""
    elif i == 6:
        return "imaging"

    elif i == 7:
        minor_index = (klass >> 2) & 0x3F
        if minor_index < len(wearable_minor_cls):
            return wearable_minor_cls[minor_index]
        else:
            return ""
    elif i == 8:
        minor_index = (klass >> 2) & 0x3F
        if minor_index < len(toy_minor_cls):
            return toy_minor_cls[minor_index]
        else:
            return ""

    if i18n:
        return _("unknown")
    else:
        return "unknown"


# First 10 bits is the category, the following 6 bits sub category
def gatt_appearance_to_name(appearance):
    cat = appearance >> 0x6
    subcat = appearance & 0x3f

    if (19 <= cat <= 48) or (55 <= cat <= 80):
        # These ranges are reserved
        logging.debug('Reserved category found: %s' % appearance)
        return gatt_appearance_categories[0][0]
    elif cat > 81:
        logging.warning('Invalid catagory found: %s' % appearance)
        return gatt_appearance_categories[0][0]

    cat_name, subcats = gatt_appearance_categories[cat]

    if subcat not in subcats:
        return cat_name
    else:
        return subcats[subcat]
