package ru.kirillius.cooler.controller.API;

public final class Message {
    private ActionType actionType;
    private DataType dataType;
    private byte value;
    private byte checksum;

    public Message(byte[] bytes) {
        if (bytes.length != 4) throw new RuntimeException("Invalid data size");
        this.actionType = ActionType.getByValue(bytes[0]);
        this.dataType = DataType.getByValue(bytes[1]);
        this.value = bytes[2];
        this.checksum = bytes[3];
    }

    public Message(ActionType actionType, DataType dataType, byte value) {
        this.actionType = actionType;
        this.dataType = dataType;
        this.value = value;
        checksum = 0;
    }

    public Message(ActionType actionType, DataType dataType) {
        this.actionType = actionType;
        this.dataType = dataType;
        this.value = 0;
        checksum = 0;
    }


    public Message(ActionType type) {
        this.actionType = type;
        this.value = 0;
        checksum = 0;
    }

    public DataType getDataType() {
        return dataType;
    }

    public void setDataType(DataType dataType) {
        this.dataType = dataType;
    }

    @Override
    public String toString() {
        return "Message{" +
                "actionType=" + actionType +
                ", dataType=" + dataType +
                ", value=" + Byte.toUnsignedInt(value) +
                '}';
    }

    public ActionType getActionType() {
        return actionType;
    }

    public void setActionType(ActionType actionType) {
        this.actionType = actionType;
    }

    public byte getValue() {
        return value;
    }

    public void setValue(byte value) {
        this.value = value;
    }

    public byte getChecksum() {
        return checksum;
    }

    public void setChecksum(byte checksum) {
        this.checksum = checksum;
    }

    public void validate() {
        checksum = calcChecksum();
    }

    public boolean isValid() {
        return checksum == calcChecksum();
    }

    private byte calcChecksum() {
        return (byte) ((byte) 18 + (byte) value + actionType.getValue() * (byte) 23 + (byte) 42 * (byte) value + (byte) 5 * dataType.getValue());
    }

    public byte[] toBytes() {
        return new byte[]{actionType.getValue(), dataType.getValue(), value, checksum};
    }

}
