package adm.vayu.retina.sync;

import adm.vayu.retina.sync.common.RetinaSyncException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RetinaSyncRunner {

    private static final Logger _logger = LoggerFactory.getLogger(RetinaSyncRunner.class);

    @Autowired
    private RetinaSyncProperties _properties;
    private Thread _syncThread = null;
    private volatile boolean _stopped = false;

    public synchronized boolean start() {

        boolean ret = false;
        if (_syncThread == null) {
            _syncThread = new Thread(() -> doStart());
            _syncThread.start();
            ret = true;
        }

        return ret;
    }

    private void doStart() {

        while (!_stopped) {
            try {
                // TrelloSync.update(ALMSync.getEntities(getConnection()));
            } catch (Exception e) {
                _logger.error("Failed to update Trello", e);
            } finally {
                sleep();
            }
        }
    }

    private void sleep() {

        try {
            long sleepTime = _properties.getInterval();
            _logger.debug(String.format("Going to sleep %d minutes", sleepTime));
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            _logger.error("Retina sync thread interrupted while sleeping", e);
        }
    }

    public void stop() {

        _logger.debug("Stopping retina sync runner...");
        _stopped = true;
        if (_syncThread != null) {
            _syncThread.interrupt();
            try {
                final int STOP_TIMEOUT = 5000;
                _syncThread.join(STOP_TIMEOUT);
            } catch (InterruptedException e) {
                throw new RetinaSyncException(e);
            } finally {
                if (_syncThread.isAlive()) {
                    _logger.warn("Controller thread did not stopped");
                }
                _syncThread = null;
            }
        }
    }
}
@@ -248,16 +248,66 @@
 rvice;%0A%0A
+import java.util.concurrent.locks.ReentrantLock;%0A%0A
 @Service
@@ -431,16 +431,64 @@
 class);%0A
+    ReentrantLock _locker = new ReentrantLock();
 %0A    @Au
@@ -643,21 +643,8 @@
 lic 
-synchronized 
 bool
@@ -687,16 +687,115 @@
  false;%0A
+        _logger.debug(%22Starting retina sync runner...%22);%0A        _locker.lock();%0A        try %7B%0A    
         
@@ -813,32 +813,36 @@
 read == null) %7B%0A
+    
             _syn
@@ -884,32 +884,36 @@
 ));%0A            
+  
+  
 _syncThread.star
@@ -929,16 +929,20 @@
         
+    
 ret = tr
@@ -937,32 +937,96 @@
     ret = true;%0A
+            %7D%0A        %7D finally %7B%0A            _locker.unlock();%0A
         %7D%0A%0A     
@@ -1016,24 +1016,25 @@
 %0A        %7D%0A%0A
+%0A
         retu
@@ -1040,32 +1040,801 @@
 urn ret;%0A    %7D%0A%0A
+    public void stop() %7B%0A%0A        _logger.debug(%22Stopping retina sync runner...%22);%0A        _stopped = true;%0A        _locker.lock();%0A        try %7B%0A            if (_syncThread != null) %7B%0A                _syncThread.interrupt();%0A                try %7B%0A                    final int STOP_TIMEOUT = 5000;%0A                    _syncThread.join(STOP_TIMEOUT);%0A                %7D catch (InterruptedException e) %7B%0A                    throw new RetinaSyncException(e);%0A                %7D finally %7B%0A                    if (_syncThread.isAlive()) %7B%0A                        _logger.warn(%22Controller thread did not stopped%22);%0A                    %7D%0A                    _syncThread = null;%0A                %7D%0A            %7D%0A        %7D finally %7B%0A            _locker.unlock();%0A        %7D%0A    %7D%0A%0A
     private void
@@ -2504,621 +2504,6 @@
    %7D
-%0A%0A    public void stop() %7B%0A%0A        _logger.debug(%22Stopping retina sync runner...%22);%0A        _stopped = true;%0A        if (_syncThread != null) %7B%0A            _syncThread.interrupt();%0A            try %7B%0A                final int STOP_TIMEOUT = 5000;%0A                _syncThread.join(STOP_TIMEOUT);%0A            %7D catch (InterruptedException e) %7B%0A                throw new RetinaSyncException(e);%0A            %7D finally %7B%0A                if (_syncThread.isAlive()) %7B%0A                    _logger.warn(%22Controller thread did not stopped%22);%0A                %7D%0A                _syncThread = null;%0A            %7D%0A        %7D%0A    %7D
 %0A%7D

improve synchronization on stop and start runner;