"""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 JointTrajectoryPoint(object):
    msg_name = "trajectory_msgs.JointTrajectoryPoint"

    __slots__ = [
        "positions_length",
        "velocities_length",
        "accelerations_length",
        "effort_length",
        "positions",
        "velocities",
        "accelerations",
        "effort",
        "time_from_start",
    ]

    __typenames__ = [
        "int32_t",
        "int32_t",
        "int32_t",
        "int32_t",
        "double",
        "double",
        "double",
        "double",
        "std_msgs.Duration",
    ]

    __dimensions__ = [
        None,
        None,
        None,
        None,
        ["positions_length"],
        ["velocities_length"],
        ["accelerations_length"],
        ["effort_length"],
        None,
    ]

    positions_length: "int32_t"
    velocities_length: "int32_t"
    accelerations_length: "int32_t"
    effort_length: "int32_t"
    positions: "double"
    velocities: "double"
    accelerations: "double"
    effort: "double"
    time_from_start: std_msgs.Duration

    def __init__(
        self,
        positions_length=0,
        velocities_length=0,
        accelerations_length=0,
        effort_length=0,
        positions=[],
        velocities=[],
        accelerations=[],
        effort=[],
        time_from_start=std_msgs.Duration(),
    ):
        # LCM Type: int32_t
        self.positions_length = positions_length
        # LCM Type: int32_t
        self.velocities_length = velocities_length
        # LCM Type: int32_t
        self.accelerations_length = accelerations_length
        # LCM Type: int32_t
        self.effort_length = effort_length
        # LCM Type: double[positions_length]
        self.positions = positions
        # LCM Type: double[velocities_length]
        self.velocities = velocities
        # LCM Type: double[accelerations_length]
        self.accelerations = accelerations
        # LCM Type: double[effort_length]
        self.effort = effort
        # LCM Type: std_msgs.Duration
        self.time_from_start = time_from_start

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

    def _encode_one(self, buf):
        buf.write(
            struct.pack(
                ">iiii",
                self.positions_length,
                self.velocities_length,
                self.accelerations_length,
                self.effort_length,
            )
        )
        buf.write(
            struct.pack(
                ">%dd" % self.positions_length, *self.positions[: self.positions_length]
            )
        )
        buf.write(
            struct.pack(
                ">%dd" % self.velocities_length,
                *self.velocities[: self.velocities_length],
            )
        )
        buf.write(
            struct.pack(
                ">%dd" % self.accelerations_length,
                *self.accelerations[: self.accelerations_length],
            )
        )
        buf.write(
            struct.pack(">%dd" % self.effort_length, *self.effort[: self.effort_length])
        )
        assert (
            self.time_from_start._get_packed_fingerprint()
            == std_msgs.Duration._get_packed_fingerprint()
        )
        self.time_from_start._encode_one(buf)

    @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.positions_length,
            self.velocities_length,
            self.accelerations_length,
            self.effort_length,
        ) = struct.unpack(">iiii", buf.read(16))
        self.positions = struct.unpack(
            ">%dd" % self.positions_length, buf.read(self.positions_length * 8)
        )
        self.velocities = struct.unpack(
            ">%dd" % self.velocities_length, buf.read(self.velocities_length * 8)
        )
        self.accelerations = struct.unpack(
            ">%dd" % self.accelerations_length, buf.read(self.accelerations_length * 8)
        )
        self.effort = struct.unpack(
            ">%dd" % self.effort_length, buf.read(self.effort_length * 8)
        )
        self.time_from_start = cls._get_field_type("time_from_start")._decode_one(buf)
        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 = (
            0x5F17DCAE9DA98292 + std_msgs.Duration._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]
