"""Parser for SensorPro BLE advertisements.

This file is shamelessly copied from the following repository:
https://github.com/Ernst79/bleparser/blob/c42ae922e1abed2720c7fac993777e1bd59c0c93/package/bleparser/brifit.py

MIT License applies.
"""
from __future__ import annotations

import logging
from struct import unpack

from bluetooth_data_tools import short_address
from bluetooth_sensor_state_data import BluetoothData
from home_assistant_bluetooth import BluetoothServiceInfo
from sensor_state_data import SensorLibrary

_LOGGER = logging.getLogger(__name__)


DEVICE_TYPES = {
    0x01: "T201",
    0x05: "T301",
}
DEFAULT_MODEL = "T201"
MFR_IDS = set(DEVICE_TYPES)


class SensorProBluetoothDeviceData(BluetoothData):
    """Date update for SensorPro Bluetooth devices."""

    def _start_update(self, service_info: BluetoothServiceInfo) -> None:
        """Update from BLE advertisement data."""
        _LOGGER.debug("Parsing sensorpro BLE advertisement data: %s", service_info)
        if 43605 not in service_info.manufacturer_data:
            return
        changed_manufacturer_data = self.changed_manufacturer_data(service_info)
        if not changed_manufacturer_data or len(changed_manufacturer_data) > 1:
            # If len(changed_manufacturer_data) > 1 it means we switched
            # ble adapters so we do not know which data is the latest
            # and we need to wait for the next update.
            return
        last_id = list(changed_manufacturer_data)[-1]

        changed = changed_manufacturer_data[last_id]
        if not changed.startswith(b"\x01\x01\xa4\xc1") and not changed.startswith(
            b"\x01\x05\xa4\xc1"
        ):
            return
        data = int(last_id).to_bytes(2, byteorder="little") + changed
        device_id = data[3]
        device_type = service_info.name or DEVICE_TYPES.get(device_id) or DEFAULT_MODEL
        name = device_type
        self.set_precision(2)
        self.set_device_type(device_id)
        self.set_title(f"{name} {short_address(service_info.address)}")
        self.set_device_name(f"{name} {short_address(service_info.address)}")
        self.set_device_manufacturer("SensorPro")
        xvalue = data[10:17]
        (volt, temp, humi, batt) = unpack(">HhHB", xvalue)
        self.update_predefined_sensor(SensorLibrary.BATTERY__PERCENTAGE, batt)
        self.update_predefined_sensor(SensorLibrary.TEMPERATURE__CELSIUS, temp / 100)
        self.update_predefined_sensor(SensorLibrary.HUMIDITY__PERCENTAGE, humi / 100)
        self.update_predefined_sensor(
            SensorLibrary.VOLTAGE__ELECTRIC_POTENTIAL_VOLT, volt / 100
        )
