/**
 * 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 java.util.Arrays;
import java.util.List;

import com.tinkerforge.IPConnection;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
 * Builds device wrappers based on their device identifier or thing name.
 * @author Erik Fleckstein - Initial contribution
 */
@NonNullByDefault
public class DeviceWrapperFactory {
    private static final List<DeviceInfo> DEVICE_INFOS;

    static {
        DEVICE_INFOS = Arrays.asList(
            BrickDaemonWrapper.DEVICE_INFO,
            BrickDCWrapper.DEVICE_INFO,
			BrickHATWrapper.DEVICE_INFO,
			BrickHATZeroWrapper.DEVICE_INFO,
			BrickIMUWrapper.DEVICE_INFO,
			BrickIMUV2Wrapper.DEVICE_INFO,
			BrickMasterWrapper.DEVICE_INFO,
			BrickREDWrapper.DEVICE_INFO,
			BrickServoWrapper.DEVICE_INFO,
			BrickSilentStepperWrapper.DEVICE_INFO,
			BrickStepperWrapper.DEVICE_INFO,
			BrickletAccelerometerWrapper.DEVICE_INFO,
			BrickletAccelerometerV2Wrapper.DEVICE_INFO,
			BrickletAirQualityWrapper.DEVICE_INFO,
			BrickletAmbientLightWrapper.DEVICE_INFO,
			BrickletAmbientLightV2Wrapper.DEVICE_INFO,
			BrickletAmbientLightV3Wrapper.DEVICE_INFO,
			BrickletAnalogInWrapper.DEVICE_INFO,
			BrickletAnalogInV2Wrapper.DEVICE_INFO,
			BrickletAnalogInV3Wrapper.DEVICE_INFO,
			BrickletAnalogOutWrapper.DEVICE_INFO,
			BrickletAnalogOutV2Wrapper.DEVICE_INFO,
			BrickletAnalogOutV3Wrapper.DEVICE_INFO,
			BrickletBarometerWrapper.DEVICE_INFO,
			BrickletBarometerV2Wrapper.DEVICE_INFO,
			BrickletCANWrapper.DEVICE_INFO,
			BrickletCANV2Wrapper.DEVICE_INFO,
			BrickletCO2Wrapper.DEVICE_INFO,
			BrickletCO2V2Wrapper.DEVICE_INFO,
			BrickletColorWrapper.DEVICE_INFO,
			BrickletColorV2Wrapper.DEVICE_INFO,
			BrickletCompassWrapper.DEVICE_INFO,
			BrickletCurrent12Wrapper.DEVICE_INFO,
			BrickletCurrent25Wrapper.DEVICE_INFO,
			BrickletDistanceIRWrapper.DEVICE_INFO,
			BrickletDistanceIRV2Wrapper.DEVICE_INFO,
			BrickletDistanceUSWrapper.DEVICE_INFO,
			BrickletDistanceUSV2Wrapper.DEVICE_INFO,
			BrickletDMXWrapper.DEVICE_INFO,
			BrickletDualButtonWrapper.DEVICE_INFO,
			BrickletDualButtonV2Wrapper.DEVICE_INFO,
			BrickletDualRelayWrapper.DEVICE_INFO,
			BrickletDustDetectorWrapper.DEVICE_INFO,
			BrickletEPaper296x128Wrapper.DEVICE_INFO,
			BrickletEnergyMonitorWrapper.DEVICE_INFO,
			BrickletGPSWrapper.DEVICE_INFO,
			BrickletGPSV2Wrapper.DEVICE_INFO,
			BrickletHallEffectWrapper.DEVICE_INFO,
			BrickletHallEffectV2Wrapper.DEVICE_INFO,
			BrickletHumidityWrapper.DEVICE_INFO,
			BrickletHumidityV2Wrapper.DEVICE_INFO,
			BrickletIMUV3Wrapper.DEVICE_INFO,
			BrickletIndustrialAnalogOutWrapper.DEVICE_INFO,
			BrickletIndustrialAnalogOutV2Wrapper.DEVICE_INFO,
			BrickletIndustrialCounterWrapper.DEVICE_INFO,
			BrickletIndustrialDigitalIn4Wrapper.DEVICE_INFO,
			BrickletIndustrialDigitalIn4V2Wrapper.DEVICE_INFO,
			BrickletIndustrialDigitalOut4Wrapper.DEVICE_INFO,
			BrickletIndustrialDigitalOut4V2Wrapper.DEVICE_INFO,
			BrickletIndustrialDual020mAWrapper.DEVICE_INFO,
			BrickletIndustrialDual020mAV2Wrapper.DEVICE_INFO,
			BrickletIndustrialDualACRelayWrapper.DEVICE_INFO,
			BrickletIndustrialDualAnalogInWrapper.DEVICE_INFO,
			BrickletIndustrialDualAnalogInV2Wrapper.DEVICE_INFO,
			BrickletIndustrialDualRelayWrapper.DEVICE_INFO,
			BrickletIndustrialPTCWrapper.DEVICE_INFO,
			BrickletIndustrialQuadRelayWrapper.DEVICE_INFO,
			BrickletIndustrialQuadRelayV2Wrapper.DEVICE_INFO,
			BrickletIO16Wrapper.DEVICE_INFO,
			BrickletIO16V2Wrapper.DEVICE_INFO,
			BrickletIO4Wrapper.DEVICE_INFO,
			BrickletIO4V2Wrapper.DEVICE_INFO,
			BrickletIsolatorWrapper.DEVICE_INFO,
			BrickletJoystickWrapper.DEVICE_INFO,
			BrickletJoystickV2Wrapper.DEVICE_INFO,
			BrickletLaserRangeFinderWrapper.DEVICE_INFO,
			BrickletLaserRangeFinderV2Wrapper.DEVICE_INFO,
			BrickletLCD128x64Wrapper.DEVICE_INFO,
			BrickletLCD16x2Wrapper.DEVICE_INFO,
			BrickletLCD20x4Wrapper.DEVICE_INFO,
			BrickletLEDStripWrapper.DEVICE_INFO,
			BrickletLEDStripV2Wrapper.DEVICE_INFO,
			BrickletLineWrapper.DEVICE_INFO,
			BrickletLinearPotiWrapper.DEVICE_INFO,
			BrickletLinearPotiV2Wrapper.DEVICE_INFO,
			BrickletLoadCellWrapper.DEVICE_INFO,
			BrickletLoadCellV2Wrapper.DEVICE_INFO,
			BrickletMoistureWrapper.DEVICE_INFO,
			BrickletMotionDetectorWrapper.DEVICE_INFO,
			BrickletMotionDetectorV2Wrapper.DEVICE_INFO,
			BrickletMotorizedLinearPotiWrapper.DEVICE_INFO,
			BrickletMultiTouchWrapper.DEVICE_INFO,
			BrickletMultiTouchV2Wrapper.DEVICE_INFO,
			BrickletNFCWrapper.DEVICE_INFO,
			BrickletNFCRFIDWrapper.DEVICE_INFO,
			BrickletOLED128x64Wrapper.DEVICE_INFO,
			BrickletOLED128x64V2Wrapper.DEVICE_INFO,
			BrickletOLED64x48Wrapper.DEVICE_INFO,
			BrickletOneWireWrapper.DEVICE_INFO,
			BrickletOutdoorWeatherWrapper.DEVICE_INFO,
			BrickletParticulateMatterWrapper.DEVICE_INFO,
			BrickletPiezoBuzzerWrapper.DEVICE_INFO,
			BrickletPiezoSpeakerWrapper.DEVICE_INFO,
			BrickletPiezoSpeakerV2Wrapper.DEVICE_INFO,
			BrickletPTCWrapper.DEVICE_INFO,
			BrickletPTCV2Wrapper.DEVICE_INFO,
			BrickletRealTimeClockWrapper.DEVICE_INFO,
			BrickletRealTimeClockV2Wrapper.DEVICE_INFO,
			BrickletRemoteSwitchWrapper.DEVICE_INFO,
			BrickletRemoteSwitchV2Wrapper.DEVICE_INFO,
			BrickletRGBLEDButtonWrapper.DEVICE_INFO,
			BrickletRGBLEDWrapper.DEVICE_INFO,
			BrickletRGBLEDMatrixWrapper.DEVICE_INFO,
			BrickletRGBLEDV2Wrapper.DEVICE_INFO,
			BrickletRotaryEncoderWrapper.DEVICE_INFO,
			BrickletRotaryEncoderV2Wrapper.DEVICE_INFO,
			BrickletRotaryPotiWrapper.DEVICE_INFO,
			BrickletRotaryPotiV2Wrapper.DEVICE_INFO,
			BrickletRS232Wrapper.DEVICE_INFO,
			BrickletRS232V2Wrapper.DEVICE_INFO,
			BrickletRS485Wrapper.DEVICE_INFO,
			BrickletSegmentDisplay4x7Wrapper.DEVICE_INFO,
			BrickletSegmentDisplay4x7V2Wrapper.DEVICE_INFO,
			BrickletSolidStateRelayWrapper.DEVICE_INFO,
			BrickletSolidStateRelayV2Wrapper.DEVICE_INFO,
			BrickletSoundIntensityWrapper.DEVICE_INFO,
			BrickletSoundPressureLevelWrapper.DEVICE_INFO,
			BrickletTemperatureWrapper.DEVICE_INFO,
			BrickletTemperatureIRWrapper.DEVICE_INFO,
			BrickletTemperatureIRV2Wrapper.DEVICE_INFO,
			BrickletTemperatureV2Wrapper.DEVICE_INFO,
			BrickletThermalImagingWrapper.DEVICE_INFO,
			BrickletThermocoupleWrapper.DEVICE_INFO,
			BrickletThermocoupleV2Wrapper.DEVICE_INFO,
			BrickletTiltWrapper.DEVICE_INFO,
			BrickletUVLightWrapper.DEVICE_INFO,
			BrickletUVLightV2Wrapper.DEVICE_INFO,
			BrickletVoltageWrapper.DEVICE_INFO,
			BrickletVoltageCurrentWrapper.DEVICE_INFO,
			BrickletVoltageCurrentV2Wrapper.DEVICE_INFO,
			BrickletXMC1400BreakoutWrapper.DEVICE_INFO,
            BrickletOutdoorWeatherSensor.DEVICE_INFO,
            BrickletOutdoorWeatherStation.DEVICE_INFO,
            RemoteSocketTypeA.DEVICE_INFO,
            RemoteSocketTypeB.DEVICE_INFO,
            RemoteSocketTypeC.DEVICE_INFO,
            RemoteDimmerTypeB.DEVICE_INFO
        );
    }

    public static DeviceInfo getDeviceInfo(int deviceIdentifier) {
        return DEVICE_INFOS.stream().filter(info -> info.deviceIdentifier == deviceIdentifier).findFirst()
                .orElseThrow(() -> new IllegalArgumentException("Unknown device identifier: " + deviceIdentifier));
    }

    public static DeviceInfo getDeviceInfo(String thingName) {
        return DEVICE_INFOS.stream().filter(info -> info.deviceThingTypeName.equals(thingName)).findFirst()
                .orElseThrow(() -> new IllegalArgumentException("Unknown device thing name: " + thingName));
    }

    public static DeviceWrapper createDevice(int deviceIdentifier, String uid, IPConnection ipcon) throws Exception {
        return (DeviceWrapper) getDeviceInfo(deviceIdentifier).deviceClass
                .getConstructor(String.class, IPConnection.class).newInstance(uid, ipcon);
    }

    public static DeviceWrapper createDevice(String thingName, String uid, IPConnection ipcon) throws Exception {
        return (DeviceWrapper) getDeviceInfo(thingName).deviceClass.getConstructor(String.class, IPConnection.class)
                .newInstance(uid, ipcon);
    }

    public static String getDeviceDisplayName(int deviceIdentifier) {
        return getDeviceInfo(deviceIdentifier).deviceDisplayName;
    }
}
