package org.commonwl.view.cwl;

import org.commonwl.view.github.GithubDetails;
import org.commonwl.view.graphviz.GraphVizService;
import org.commonwl.view.workflow.Workflow;
import org.commonwl.view.workflow.WorkflowRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * Replace existing workflow with the one given by cwltool
 */
@Component
@EnableAsync
public class CWLToolRunner {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final WorkflowRepository workflowRepository;
    private final CWLService cwlService;
    private final GraphVizService graphVizService;
    private final String cwlToolVersion;

    @Autowired
    public CWLToolRunner(WorkflowRepository workflowRepository,
                         CWLService cwlService,
                         CWLTool cwlTool,
                         GraphVizService graphVizService) {
        this.workflowRepository = workflowRepository;
        this.cwlService = cwlService;
        this.graphVizService = graphVizService;
        this.cwlToolVersion = cwlTool.getVersion();
    }

    @Async
    public void updateModelWithCwltool(GithubDetails githubInfo,
                                       String latestCommit,
                                       String packedWorkflowID)
            throws IOException, InterruptedException {

        Workflow workflow = workflowRepository.findByRetrievedFrom(githubInfo);

        // Chance that this thread could be done before workflow model is saved
        int attempts = 5;
        while (attempts > 0 && workflow == null) {
            // Delay this thread by 0.5s and try again until success or too many attempts
            Thread.sleep(1000L);
            workflow = workflowRepository.findByRetrievedFrom(githubInfo);
            attempts--;
        }

        // Parse using cwltool and replace in database
        try {
            Workflow newWorkflow = cwlService.parseWorkflowWithCwltool(
                    githubInfo, latestCommit, packedWorkflowID);

            workflowRepository.delete(workflow);
            graphVizService.deleteCache(workflow.getID());

            newWorkflow.setId(workflow.getID());
            newWorkflow.setRetrievedOn(workflow.getRetrievedOn());
            newWorkflow.setRetrievedFrom(githubInfo);
            newWorkflow.setLastCommit(latestCommit);
            newWorkflow.setCwltoolStatus(Workflow.Status.SUCCESS);
            newWorkflow.setCwltoolVersion(cwlToolVersion);
            workflowRepository.save(newWorkflow);
        } catch (CWLValidationException ex) {
            logger.error(ex.getMessage(), ex);
            workflow.setCwltoolStatus(Workflow.Status.ERROR);
            workflow.setCwltoolLog(ex.getMessage());
            workflowRepository.save(workflow);
        }

    }

}

@@ -2151,16 +2151,17 @@
   try %7B%0A
+%0A
         
@@ -2748,16 +2748,17 @@
 rsion);%0A
+%0A
         
@@ -2791,32 +2791,33 @@
 e(newWorkflow);%0A
+%0A
         %7D catch 
@@ -2955,16 +2955,16 @@
 ERROR);%0A
-
         
@@ -3060,23 +3060,440 @@
 );%0A        %7D
+ catch (Exception ex) %7B%0A            logger.error(%22Unexpected error%22, ex);%0A            workflow.setCwltoolStatus(Workflow.Status.ERROR);%0A            workflow.setCwltoolLog(%22Whoops! Cwltool ran successfully, but an unexpected %22 +%0A                    %22error occurred in CWLViewer!%5Cn%22 +%0A                    %22Help us by reporting it on Gitter or a Github issue%5Cn%22);%0A            workflowRepository.save(workflow);%0A        %7D
 %0A%0A    %7D%0A%0A%7D%0A

Improve error handling during rdf parsing