package ev3dev.hardware;

import ev3dev.utils.Sysfs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.List;
import java.util.Properties;

/**
 * This class been designed to discover if the library is used in:
 *
 * - EV3 Brick
 * - Raspberry Pi 1 + PiStorms
 * - Raspberry Pi 1 + BrickPi
 * 
 * @author Juan Antonio Breña Moral
 *
 * At the moment, the class extends from Device, but close method doesn´ close any real resource.
 */


public abstract class EV3DevDevice {

    private static final Logger LOGGER = LoggerFactory.getLogger(EV3DevDevice.class);

    protected final Properties ev3DevProperties;
    protected final EV3DevPlatform CURRENT_PLATFORM;

    protected static final String LEGO_PORT = "lego-port";
    protected static final String ADDRESS = "address";
    protected static final String LEGO_SENSOR = "lego-sensor";
    protected static final String MODE = "mode";
    protected static final String DEVICE = "set_device";

    protected File PATH_DEVICE = null;

    public EV3DevDevice() {

        final EV3DevPropertyLoader ev3DevPropertyLoader = new EV3DevPropertyLoader();
        ev3DevProperties = ev3DevPropertyLoader.getEV3DevProperties();
        final EV3DevPlatforms ev3DevPlatforms = new EV3DevPlatforms();
        CURRENT_PLATFORM = ev3DevPlatforms.getPlatform();
    }

    //TODO Rename method to detect
    /**
     * This method matches a input with the internal position in EV3Dev.
     * @param type type
     * @param portName port
     */
    protected void detect(final String type, final String portName) {
        final String devicePath = EV3DevFileSystem.getRootPath() + "/" + type;
        if(LOGGER.isTraceEnabled())
            LOGGER.trace("Retrieving devices in path: ", devicePath);
        final List<File> deviceAvailables = Sysfs.getElements(devicePath);
        boolean connected = false;
        if(LOGGER.isTraceEnabled())
            LOGGER.trace("Checking devices on: {}", devicePath);
        String pathDeviceName;
        int deviceCounter = 1;
        for (File deviceAvailable : deviceAvailables) {
            PATH_DEVICE = deviceAvailable;
            pathDeviceName = PATH_DEVICE + "/" + ADDRESS;
            if(LOGGER.isTraceEnabled())
                LOGGER.trace("Device {}:", deviceCounter);
            String result = Sysfs.readString(pathDeviceName);
            if(LOGGER.isTraceEnabled())
                LOGGER.trace("Port expected: {}, actual: {}.", portName, result);
            //TODO Review to use equals. It is more strict
            if (result.contains(portName)) {
                if(LOGGER.isDebugEnabled())
                    LOGGER.debug("Detected device on path: {}, {}", pathDeviceName, result);
                connected = true;
                break;
            } else {
                if(LOGGER.isTraceEnabled())
                    LOGGER.trace("Skipped device");
            }
            deviceCounter++;
        }

        if(!connected){
            throw new RuntimeException("The device was not detected in: " + portName);
        }
    }

    /**
     * Returns the value of an attribute supported for a Device
     *
     * @param attribute attribute
     * @return value
     */
    protected String getStringAttribute(final String attribute){
        return Sysfs.readString(PATH_DEVICE + "/" +  attribute);
    }

    /**
     * Returns the value of an attribute supported for a Device
     *
     * @param attribute attribute
     * @return value
     */
    protected int getIntegerAttribute(final String attribute){
        return Sysfs.readInteger(PATH_DEVICE + "/" +  attribute);
    }

    /**
     * Set a value on an attribute
     *
     * @param attribute attribute
     * @param value value
     */
    protected void setStringAttribute(final String attribute, final String value){
        final boolean result = Sysfs.writeString(this.PATH_DEVICE + "/" +  attribute, value);
        if(!result){
            throw new RuntimeException("Operation not executed: " + this.PATH_DEVICE + "/" +  attribute + " with value " + value);
        }
    }

    /**
     * Set a value on an attribute
     *
     * @param attribute attribute
     * @param value value
     */
    protected void setIntegerAttribute(final String attribute, final int value){
        final boolean result = Sysfs.writeInteger(this.PATH_DEVICE + "/" +  attribute, value);
        if(!result){
            throw new RuntimeException("Operation not executed: " + this.PATH_DEVICE + "/" +  attribute + " with value " + value);
        }
    }
	
}

@@ -3593,56 +3593,626 @@
 urn 
-Sysfs.readInteger(PATH_DEVICE + %22/%22 +  attribute
+Integer.parseInt(getStringAttribute(attribute));%0A    %7D%0A%0A    /**%0A     * Returns the value of an attribute supported for a Device%0A     *%0A     * @param attribute attribute%0A     * @return value%0A     */%0A    protected float getFloatAttribute(final String attribute) %7B%0A        return Float.parseFloat(getStringAttribute(attribute));%0A    %7D%0A%0A    /**%0A     * Reads the specified value from the sensor.%0A     *%0A     * @param index Index of the returned value, e.g. value&lt;index&gt; will be read.%0A     * @return Measured value.%0A     */%0A    public float readValue(final int index) %7B%0A        return getFloatAttribute(%22value%22 + index
 );%0A 
@@ -4800,32 +4800,29 @@
     */%0A    p
-rotected
+ublic
  void setInt
@@ -4871,24 +4871,25 @@
 l int value)
+ 
 %7B%0A        fi
@@ -4890,256 +4890,63 @@
     
-final boolean result = Sysfs.writeInteger(this.PATH_DEVICE + %22/%22 +  attribute, value);%0A        if(!result)%7B%0A            throw new RuntimeException(%22Operation not executed: %22 + this.PATH_DEVICE + %22/%22 +  attribute + %22 with value %22 + value);%0A        %7D
+setStringAttribute(attribute, Integer.toString(value));
 %0A   

Add value read function to EV3DevDevice