"""LCM type definitions
This file automatically generated by lcm.
DO NOT MODIFY BY HAND!!!!
"""

from io import BytesIO
import struct
import sys

from lcm_msgs import std_msgs


class BatteryState(object):
    msg_name = "sensor_msgs.BatteryState"

    __slots__ = [
        "cell_voltage_length",
        "cell_temperature_length",
        "header",
        "voltage",
        "temperature",
        "current",
        "charge",
        "capacity",
        "design_capacity",
        "percentage",
        "power_supply_status",
        "power_supply_health",
        "power_supply_technology",
        "present",
        "cell_voltage",
        "cell_temperature",
        "location",
        "serial_number",
    ]

    __typenames__ = [
        "int32_t",
        "int32_t",
        "std_msgs.Header",
        "float",
        "float",
        "float",
        "float",
        "float",
        "float",
        "float",
        "byte",
        "byte",
        "byte",
        "boolean",
        "float",
        "float",
        "string",
        "string",
    ]

    __dimensions__ = [
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        ["cell_voltage_length"],
        ["cell_temperature_length"],
        None,
        None,
    ]

    cell_voltage_length: "int32_t"
    cell_temperature_length: "int32_t"
    header: std_msgs.Header
    voltage: "float"
    temperature: "float"
    current: "float"
    charge: "float"
    capacity: "float"
    design_capacity: "float"
    percentage: "float"
    power_supply_status: "byte"
    power_supply_health: "byte"
    power_supply_technology: "byte"
    present: "boolean"
    cell_voltage: "float"
    cell_temperature: "float"
    location: "string"
    serial_number: "string"

    POWER_SUPPLY_STATUS_UNKNOWN = 0
    POWER_SUPPLY_STATUS_CHARGING = 1
    POWER_SUPPLY_STATUS_DISCHARGING = 2
    POWER_SUPPLY_STATUS_NOT_CHARGING = 3
    POWER_SUPPLY_STATUS_FULL = 4
    POWER_SUPPLY_HEALTH_UNKNOWN = 0
    POWER_SUPPLY_HEALTH_GOOD = 1
    POWER_SUPPLY_HEALTH_OVERHEAT = 2
    POWER_SUPPLY_HEALTH_DEAD = 3
    POWER_SUPPLY_HEALTH_OVERVOLTAGE = 4
    POWER_SUPPLY_HEALTH_UNSPEC_FAILURE = 5
    POWER_SUPPLY_HEALTH_COLD = 6
    POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE = 7
    POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE = 8
    POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0
    POWER_SUPPLY_TECHNOLOGY_NIMH = 1
    POWER_SUPPLY_TECHNOLOGY_LION = 2
    POWER_SUPPLY_TECHNOLOGY_LIPO = 3
    POWER_SUPPLY_TECHNOLOGY_LIFE = 4
    POWER_SUPPLY_TECHNOLOGY_NICD = 5
    POWER_SUPPLY_TECHNOLOGY_LIMN = 6

    def __init__(
        self,
        cell_voltage_length=0,
        cell_temperature_length=0,
        header=std_msgs.Header(),
        voltage=0.0,
        temperature=0.0,
        current=0.0,
        charge=0.0,
        capacity=0.0,
        design_capacity=0.0,
        percentage=0.0,
        power_supply_status=0,
        power_supply_health=0,
        power_supply_technology=0,
        present=False,
        cell_voltage=[],
        cell_temperature=[],
        location="",
        serial_number="",
    ):
        # LCM Type: int32_t
        self.cell_voltage_length = cell_voltage_length
        # LCM Type: int32_t
        self.cell_temperature_length = cell_temperature_length
        # LCM Type: std_msgs.Header
        self.header = header
        # LCM Type: float
        self.voltage = voltage
        # LCM Type: float
        self.temperature = temperature
        # LCM Type: float
        self.current = current
        # LCM Type: float
        self.charge = charge
        # LCM Type: float
        self.capacity = capacity
        # LCM Type: float
        self.design_capacity = design_capacity
        # LCM Type: float
        self.percentage = percentage
        # LCM Type: byte
        self.power_supply_status = power_supply_status
        # LCM Type: byte
        self.power_supply_health = power_supply_health
        # LCM Type: byte
        self.power_supply_technology = power_supply_technology
        # LCM Type: boolean
        self.present = present
        # LCM Type: float[cell_voltage_length]
        self.cell_voltage = cell_voltage
        # LCM Type: float[cell_temperature_length]
        self.cell_temperature = cell_temperature
        # LCM Type: string
        self.location = location
        # LCM Type: string
        self.serial_number = serial_number

    def lcm_encode(self):
        buf = BytesIO()
        buf.write(BatteryState._get_packed_fingerprint())
        self._encode_one(buf)
        return buf.getvalue()

    def _encode_one(self, buf):
        buf.write(
            struct.pack(">ii", self.cell_voltage_length, self.cell_temperature_length)
        )
        assert (
            self.header._get_packed_fingerprint()
            == std_msgs.Header._get_packed_fingerprint()
        )
        self.header._encode_one(buf)
        buf.write(
            struct.pack(
                ">fffffffBBBb",
                self.voltage,
                self.temperature,
                self.current,
                self.charge,
                self.capacity,
                self.design_capacity,
                self.percentage,
                self.power_supply_status,
                self.power_supply_health,
                self.power_supply_technology,
                self.present,
            )
        )
        buf.write(
            struct.pack(
                ">%df" % self.cell_voltage_length,
                *self.cell_voltage[: self.cell_voltage_length],
            )
        )
        buf.write(
            struct.pack(
                ">%df" % self.cell_temperature_length,
                *self.cell_temperature[: self.cell_temperature_length],
            )
        )
        __location_encoded = self.location.encode("utf-8")
        buf.write(struct.pack(">I", len(__location_encoded) + 1))
        buf.write(__location_encoded)
        buf.write(b"\0")
        __serial_number_encoded = self.serial_number.encode("utf-8")
        buf.write(struct.pack(">I", len(__serial_number_encoded) + 1))
        buf.write(__serial_number_encoded)
        buf.write(b"\0")

    @classmethod
    def lcm_decode(cls, data: bytes):
        if hasattr(data, "read"):
            buf = data
        else:
            buf = BytesIO(data)
        if buf.read(8) != cls._get_packed_fingerprint():
            raise ValueError("Decode error")
        return cls._decode_one(buf)

    @classmethod
    def _decode_one(cls, buf):
        self = cls()
        self.cell_voltage_length, self.cell_temperature_length = struct.unpack(
            ">ii", buf.read(8)
        )
        self.header = cls._get_field_type("header")._decode_one(buf)
        (
            self.voltage,
            self.temperature,
            self.current,
            self.charge,
            self.capacity,
            self.design_capacity,
            self.percentage,
            self.power_supply_status,
            self.power_supply_health,
            self.power_supply_technology,
        ) = struct.unpack(">fffffffBBB", buf.read(31))
        self.present = bool(struct.unpack("b", buf.read(1))[0])
        self.cell_voltage = struct.unpack(
            ">%df" % self.cell_voltage_length, buf.read(self.cell_voltage_length * 4)
        )
        self.cell_temperature = struct.unpack(
            ">%df" % self.cell_temperature_length,
            buf.read(self.cell_temperature_length * 4),
        )
        __location_len = struct.unpack(">I", buf.read(4))[0]
        self.location = buf.read(__location_len)[:-1].decode("utf-8", "replace")
        __serial_number_len = struct.unpack(">I", buf.read(4))[0]
        self.serial_number = buf.read(__serial_number_len)[:-1].decode(
            "utf-8", "replace"
        )
        return self

    @classmethod
    def _get_field_type(cls, field_name):
        """Get the type for a field from annotations."""
        annotation = cls.__annotations__.get(field_name)
        if annotation is None:
            return None
        if isinstance(annotation, str):
            module = sys.modules[cls.__module__]
            if hasattr(module, annotation):
                return getattr(module, annotation)
            return None
        return annotation

    @classmethod
    def _get_hash_recursive(cls, parents):
        if cls in parents:
            return 0
        newparents = parents + [cls]
        tmphash = (
            0x8F419FB94C3B774D + std_msgs.Header._get_hash_recursive(newparents)
        ) & 0xFFFFFFFFFFFFFFFF
        tmphash = (
            ((tmphash << 1) & 0xFFFFFFFFFFFFFFFF) + (tmphash >> 63)
        ) & 0xFFFFFFFFFFFFFFFF
        return tmphash

    _packed_fingerprint = None

    @classmethod
    def _get_packed_fingerprint(cls):
        if cls._packed_fingerprint is None:
            cls._packed_fingerprint = struct.pack(">Q", cls._get_hash_recursive([]))
        return cls._packed_fingerprint

    def get_hash(self):
        """Get the LCM hash of the struct"""
        return struct.unpack(">Q", cls._get_packed_fingerprint())[0]
