/**
 * Copyright (c) 2010-2020 Contributors to the openHAB project
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */

 /* ***********************************************************
 * This file was automatically generated on 2022-01-03.      *
 *                                                           *
 * openHAB Bindings Version 2.0.0                            *
 *                                                           *
 * If you have a bugfix for this file and want to commit it, *
 * please fix the bug in the generator. You can find a link  *
 * to the generators git repository on tinkerforge.com       *
 *************************************************************/

package org.openhab.binding.tinkerforge.internal.device;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jdt.annotation.NonNull;
import org.openhab.binding.tinkerforge.internal.handler.DeviceHandler;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.binding.ThingActions;
import org.eclipse.smarthome.core.thing.binding.ThingActionsScope;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;
import org.eclipse.smarthome.core.types.RefreshType;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.openhab.core.automation.annotation.ActionInput;
import org.openhab.core.automation.annotation.ActionOutput;
import org.openhab.core.automation.annotation.RuleAction;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import java.util.Map;
import java.util.HashMap;

import com.tinkerforge.TinkerforgeException;
import com.tinkerforge.BrickletCANV2;

/**
 * Passes through actions of the CAN Bricklet 2.0.
 * @author Erik Fleckstein - Initial contribution
 */
@ThingActionsScope(name = "tinkerforge")
@NonNullByDefault
public class BrickletCANV2Actions implements ThingActions, IBrickletCANV2Actions {

    private @Nullable DeviceHandler handler;

    @Override
    public void setThingHandler(@Nullable ThingHandler handler) { this.handler = (DeviceHandler) handler; }

    @Override
    public @Nullable ThingHandler getThingHandler() { return handler; }

    private static IBrickletCANV2Actions invokeMethodOf(@Nullable ThingActions actions) {
        if (actions == null) {
            throw new IllegalArgumentException("actions cannot be null");
        }
        if (actions.getClass().getName().equals(BrickletCANV2Actions.class.getName())) {
            if (actions instanceof IBrickletCANV2Actions) {
                return (IBrickletCANV2Actions) actions;
            } else {
                return (IBrickletCANV2Actions) Proxy.newProxyInstance(IBrickletCANV2Actions.class.getClassLoader(),
                        new Class[] { IBrickletCANV2Actions.class }, (Object proxy, Method method, Object[] args) -> {
                            Method m = actions.getClass().getDeclaredMethod(method.getName(),
                                    method.getParameterTypes());
                            return m.invoke(actions, args);
                        });
            }
        }
        throw new IllegalArgumentException("Actions is not an instance of BrickletCANV2Actions");
    }

    
    @Override
    @RuleAction(label = "Write Frame")
    public @ActionOutput(name = "success", type="boolean")
           Map<String, Object> brickletCANV2WriteFrame(
            @ActionInput(name = "frameType") int frameType,
            @ActionInput(name = "identifier") long identifier,
            @ActionInput(name = "data") int[] data) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        boolean value = dev.writeFrame(frameType, identifier, data);
        
        result.put("success", value);
        return result;
    }

    public static Map<String, Object> brickletCANV2WriteFrame(@Nullable ThingActions actions, int frameType, long identifier, int[] data) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2WriteFrame(frameType, identifier, data);
    }


    @Override
    @RuleAction(label = "Read Frame")
    public @ActionOutput(name = "success", type="boolean")
           @ActionOutput(name = "frameType", type="int")
           @ActionOutput(name = "identifier", type="long")
           @ActionOutput(name = "data", type="int[]")
           Map<String, Object> brickletCANV2ReadFrame(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickletCANV2.ReadFrame value = dev.readFrame();
        
        result.put("success", value.success);
        result.put("frameType", value.frameType);
        result.put("identifier", value.identifier);
        result.put("data", value.data);
        return result;
    }

    public static Map<String, Object> brickletCANV2ReadFrame(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2ReadFrame();
    }


    @Override
    @RuleAction(label = "Get Transceiver Configuration")
    public @ActionOutput(name = "baudRate", type="long")
           @ActionOutput(name = "samplePoint", type="int")
           @ActionOutput(name = "transceiverMode", type="int")
           Map<String, Object> brickletCANV2GetTransceiverConfiguration(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickletCANV2.TransceiverConfiguration value = dev.getTransceiverConfiguration();
        
        result.put("baudRate", value.baudRate);
        result.put("samplePoint", value.samplePoint);
        result.put("transceiverMode", value.transceiverMode);
        return result;
    }

    public static Map<String, Object> brickletCANV2GetTransceiverConfiguration(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2GetTransceiverConfiguration();
    }

    @Override
    @RuleAction(label = "Set Queue Configuration")
    public void brickletCANV2SetQueueConfiguration(
            @ActionInput(name = "writeBufferSize") int writeBufferSize,
            @ActionInput(name = "writeBufferTimeout") int writeBufferTimeout,
            @ActionInput(name = "writeBacklogSize") int writeBacklogSize,
            @ActionInput(name = "readBufferSizes") int[] readBufferSizes,
            @ActionInput(name = "readBacklogSize") int readBacklogSize) throws TinkerforgeException {
        DeviceHandler h = handler;
        if(h == null) {
            return;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return;
        }
        dev.setQueueConfiguration(writeBufferSize, writeBufferTimeout, writeBacklogSize, readBufferSizes, readBacklogSize);
        
    }

    public static void brickletCANV2SetQueueConfiguration(@Nullable ThingActions actions, int writeBufferSize, int writeBufferTimeout, int writeBacklogSize, int[] readBufferSizes, int readBacklogSize) throws TinkerforgeException {
        invokeMethodOf(actions).brickletCANV2SetQueueConfiguration(writeBufferSize, writeBufferTimeout, writeBacklogSize, readBufferSizes, readBacklogSize);
    }


    @Override
    @RuleAction(label = "Get Queue Configuration")
    public @ActionOutput(name = "writeBufferSize", type="int")
           @ActionOutput(name = "writeBufferTimeout", type="int")
           @ActionOutput(name = "writeBacklogSize", type="int")
           @ActionOutput(name = "readBufferSizes", type="int[]")
           @ActionOutput(name = "readBacklogSize", type="int")
           Map<String, Object> brickletCANV2GetQueueConfiguration(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickletCANV2.QueueConfiguration value = dev.getQueueConfiguration();
        
        result.put("writeBufferSize", value.writeBufferSize);
        result.put("writeBufferTimeout", value.writeBufferTimeout);
        result.put("writeBacklogSize", value.writeBacklogSize);
        result.put("readBufferSizes", value.readBufferSizes);
        result.put("readBacklogSize", value.readBacklogSize);
        return result;
    }

    public static Map<String, Object> brickletCANV2GetQueueConfiguration(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2GetQueueConfiguration();
    }

    @Override
    @RuleAction(label = "Set Read Filter Configuration")
    public void brickletCANV2SetReadFilterConfiguration(
            @ActionInput(name = "bufferIndex") int bufferIndex,
            @ActionInput(name = "filterMode") int filterMode,
            @ActionInput(name = "filterMask") long filterMask,
            @ActionInput(name = "filterIdentifier") long filterIdentifier) throws TinkerforgeException {
        DeviceHandler h = handler;
        if(h == null) {
            return;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return;
        }
        dev.setReadFilterConfiguration(bufferIndex, filterMode, filterMask, filterIdentifier);
        
    }

    public static void brickletCANV2SetReadFilterConfiguration(@Nullable ThingActions actions, int bufferIndex, int filterMode, long filterMask, long filterIdentifier) throws TinkerforgeException {
        invokeMethodOf(actions).brickletCANV2SetReadFilterConfiguration(bufferIndex, filterMode, filterMask, filterIdentifier);
    }


    @Override
    @RuleAction(label = "Get Read Filter Configuration")
    public @ActionOutput(name = "filterMode", type="int")
           @ActionOutput(name = "filterMask", type="long")
           @ActionOutput(name = "filterIdentifier", type="long")
           Map<String, Object> brickletCANV2GetReadFilterConfiguration(
            @ActionInput(name = "bufferIndex") int bufferIndex) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickletCANV2.ReadFilterConfiguration value = dev.getReadFilterConfiguration(bufferIndex);
        
        result.put("filterMode", value.filterMode);
        result.put("filterMask", value.filterMask);
        result.put("filterIdentifier", value.filterIdentifier);
        return result;
    }

    public static Map<String, Object> brickletCANV2GetReadFilterConfiguration(@Nullable ThingActions actions, int bufferIndex) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2GetReadFilterConfiguration(bufferIndex);
    }


    @Override
    @RuleAction(label = "Get Error Log")
    public @ActionOutput(name = "transceiverState", type="int")
           @ActionOutput(name = "transceiverWriteErrorLevel", type="int")
           @ActionOutput(name = "transceiverReadErrorLevel", type="int")
           @ActionOutput(name = "transceiverStuffingErrorCount", type="long")
           @ActionOutput(name = "transceiverFormatErrorCount", type="long")
           @ActionOutput(name = "transceiverACKErrorCount", type="long")
           @ActionOutput(name = "transceiverBit1ErrorCount", type="long")
           @ActionOutput(name = "transceiverBit0ErrorCount", type="long")
           @ActionOutput(name = "transceiverCRCErrorCount", type="long")
           @ActionOutput(name = "writeBufferTimeoutErrorCount", type="long")
           @ActionOutput(name = "readBufferOverflowErrorCount", type="long")
           @ActionOutput(name = "readBufferOverflowErrorOccurred", type="boolean[]")
           @ActionOutput(name = "readBacklogOverflowErrorCount", type="long")
           Map<String, Object> brickletCANV2GetErrorLog(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickletCANV2.ErrorLog value = dev.getErrorLog();
        
        result.put("transceiverState", value.transceiverState);
        result.put("transceiverWriteErrorLevel", value.transceiverWriteErrorLevel);
        result.put("transceiverReadErrorLevel", value.transceiverReadErrorLevel);
        result.put("transceiverStuffingErrorCount", value.transceiverStuffingErrorCount);
        result.put("transceiverFormatErrorCount", value.transceiverFormatErrorCount);
        result.put("transceiverACKErrorCount", value.transceiverACKErrorCount);
        result.put("transceiverBit1ErrorCount", value.transceiverBit1ErrorCount);
        result.put("transceiverBit0ErrorCount", value.transceiverBit0ErrorCount);
        result.put("transceiverCRCErrorCount", value.transceiverCRCErrorCount);
        result.put("writeBufferTimeoutErrorCount", value.writeBufferTimeoutErrorCount);
        result.put("readBufferOverflowErrorCount", value.readBufferOverflowErrorCount);
        result.put("readBufferOverflowErrorOccurred", value.readBufferOverflowErrorOccurred);
        result.put("readBacklogOverflowErrorCount", value.readBacklogOverflowErrorCount);
        return result;
    }

    public static Map<String, Object> brickletCANV2GetErrorLog(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2GetErrorLog();
    }


    @Override
    @RuleAction(label = "Read UID")
    public @ActionOutput(name = "uid", type="long")
           Map<String, Object> brickletCANV2ReadUID(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        long value = dev.readUID();
        
        result.put("uid", value);
        return result;
    }

    public static Map<String, Object> brickletCANV2ReadUID(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2ReadUID();
    }


    @Override
    @RuleAction(label = "Get Chip Temperature")
    public @ActionOutput(name = "temperature", type="int")
           Map<String, Object> brickletCANV2GetChipTemperature(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        int value = dev.getChipTemperature();
        
        result.put("temperature", value);
        return result;
    }

    public static Map<String, Object> brickletCANV2GetChipTemperature(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2GetChipTemperature();
    }


    @Override
    @RuleAction(label = "Get Status LED Config")
    public @ActionOutput(name = "config", type="int")
           Map<String, Object> brickletCANV2GetStatusLEDConfig(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        int value = dev.getStatusLEDConfig();
        
        result.put("config", value);
        return result;
    }

    public static Map<String, Object> brickletCANV2GetStatusLEDConfig(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2GetStatusLEDConfig();
    }


    @Override
    @RuleAction(label = "Get SPITFP Error Count")
    public @ActionOutput(name = "errorCountAckChecksum", type="long")
           @ActionOutput(name = "errorCountMessageChecksum", type="long")
           @ActionOutput(name = "errorCountFrame", type="long")
           @ActionOutput(name = "errorCountOverflow", type="long")
           Map<String, Object> brickletCANV2GetSPITFPErrorCount(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickletCANV2.SPITFPErrorCount value = dev.getSPITFPErrorCount();
        
        result.put("errorCountAckChecksum", value.errorCountAckChecksum);
        result.put("errorCountMessageChecksum", value.errorCountMessageChecksum);
        result.put("errorCountFrame", value.errorCountFrame);
        result.put("errorCountOverflow", value.errorCountOverflow);
        return result;
    }

    public static Map<String, Object> brickletCANV2GetSPITFPErrorCount(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2GetSPITFPErrorCount();
    }

    @Override
    @RuleAction(label = "Reset")
    public void brickletCANV2Reset(
            ) throws TinkerforgeException {
        DeviceHandler h = handler;
        if(h == null) {
            return;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return;
        }
        dev.reset();
        
    }

    public static void brickletCANV2Reset(@Nullable ThingActions actions) throws TinkerforgeException {
        invokeMethodOf(actions).brickletCANV2Reset();
    }


    @Override
    @RuleAction(label = "Get Identity")
    public @ActionOutput(name = "uid", type="String")
           @ActionOutput(name = "connectedUid", type="String")
           @ActionOutput(name = "position", type="char")
           @ActionOutput(name = "hardwareVersion", type="short[]")
           @ActionOutput(name = "firmwareVersion", type="short[]")
           @ActionOutput(name = "deviceIdentifier", type="int")
           Map<String, Object> brickletCANV2GetIdentity(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickletCANV2Wrapper dev = ((@Nullable BrickletCANV2Wrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickletCANV2.Identity value = dev.getIdentity();
        
        result.put("uid", value.uid);
        result.put("connectedUid", value.connectedUid);
        result.put("position", value.position);
        result.put("hardwareVersion", value.hardwareVersion);
        result.put("firmwareVersion", value.firmwareVersion);
        result.put("deviceIdentifier", value.deviceIdentifier);
        return result;
    }

    public static Map<String, Object> brickletCANV2GetIdentity(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickletCANV2GetIdentity();
    }
}
