package org.robbins.raspberry.pi.service;

import com.pi4j.io.gpio.*;
import org.robbins.raspberry.pi.exceptions.RaspberryPiAppException;
import org.robbins.raspberry.pi.model.PiAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service("blinkLight")
public class BlinkLightActionImpl implements PiActionService {

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

    @Value("${blink.delay}")
    private long blinkDelay;

    GpioController gpio;
    GpioPinDigitalOutput pin;

    @Override
    public void invokeAction(final PiAction action) throws RaspberryPiAppException {
        LOGGER.debug("Blinking Light service for action: {}", action);

        try {
            final long blinkDuration = calculateBlinkDurationInMilliseconds(Long.parseLong(action.getValue()));

            // create gpio controller
            gpio = GpioFactory.getInstance();

            // provision gpio pin #01 as an output pin
            pin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01);

            LOGGER.debug("Blinking LED with delay: {}, and duration: {}", blinkDelay, blinkDuration);
            pin.blink(blinkDelay, blinkDuration);
        }
        catch (Exception e) {
            LOGGER.debug("Error while blinking: {}", e.getMessage());
            throw new RaspberryPiAppException(e.getMessage());
        }
        finally {
            // stop all GPIO activity/threads by shutting down the GPIO controller
            // (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks)
            if (gpio != null) {
                LOGGER.debug("Shutting down GPIO");
                gpio.shutdown();
                gpio.unprovisionPin(pin);
            }
            else {
                LOGGER.debug("Unable to shutdown GPIO.  There is no GPIO instance");
            }
        }
    }

    private void blinkLight(final GpioPinDigitalOutput pin, int blinkCount) throws RaspberryPiAppException {

        try {
            for (int i = 0; i < blinkCount; i++) {
                pin.high();
                LOGGER.debug("--> GPIO state should be: ON");

                Thread.sleep(blinkDelay);

                // turn off gpio pin #01
                pin.low();
                LOGGER.debug("--> GPIO state should be: OFF");

                Thread.sleep(blinkDelay);
            }
        }
        catch (InterruptedException e) {
            throw new RaspberryPiAppException(e.getMessage());
        }
    }

    private long calculateBlinkDurationInMilliseconds(final long timeInSeconds) {
        return 1000 * timeInSeconds;
    }
}

@@ -861,16 +861,112 @@
 Duration
+InSeconds = Long.parseLong(action.getValue();%0A            final long blinkDurationInMilliseconds
  = calcu
@@ -1001,40 +1001,30 @@
 nds(
-Long.parseLong(action.getValue()
+blinkDurationInSeconds
 ));%0A
@@ -1324,35 +1324,51 @@
 y, blinkDuration
+InMilliseconds
 );%0A
+//
             pin.
@@ -1401,33 +1401,87 @@
 ation);%0A        
-%7D
+    blinkLight(pin, blinkDurationInSeconds);%0A        %7D%0A
 %0A        catch (
@@ -2209,19 +2209,20 @@
 ut pin, 
-int
+long
  blinkCo

refactor blinking service