package pingis.services.sandbox;

import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import pingis.config.SandboxSubmissionProperties;
import pingis.entities.sandbox.Submission;
import pingis.entities.sandbox.SubmissionStatus;
import pingis.repositories.sandbox.SubmissionRepository;

@Service
public class SubmissionSenderService {

  private final Logger logger = LoggerFactory.getLogger(SubmissionSenderService.class);

  private static final String SUBMISSION_FILENAME = "submission.tar";

  private RestTemplate restTemplate;

  private final SandboxSubmissionProperties sandboxSubmissionProperties;

  private final SubmissionRepository submissionRepository;

  @Autowired
  public SubmissionSenderService(RestTemplateBuilder restTemplateBuilder,
      SandboxSubmissionProperties sandboxSubmissionProperties,
      SubmissionRepository submissionRepository) {
    this.sandboxSubmissionProperties = sandboxSubmissionProperties;
    this.submissionRepository = submissionRepository;

    restTemplate = restTemplateBuilder
        .rootUri(sandboxSubmissionProperties.getSandboxUrl())
        .build();
  }

  private HttpEntity<MultiValueMap<String, Object>> buildRequestEntity(byte[] packaged,
      String notifyToken,
      String notifyUrl) {
    MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();

    HttpHeaders textHeaders = new HttpHeaders();
    textHeaders.setContentType(MediaType.TEXT_PLAIN);

    HttpHeaders binaryHeaders = new HttpHeaders();
    binaryHeaders.setContentDispositionFormData("file", SUBMISSION_FILENAME);

    map.add("file", new HttpEntity<>(new ByteArrayResource(packaged), binaryHeaders));
    map.add("token", new HttpEntity<>(notifyToken, textHeaders));
    map.add("notify", new HttpEntity<>(notifyUrl, textHeaders));

    return new HttpEntity<>(map);
  }

  public Submission sendSubmission(Submission submission, byte[] packaged) {
    submission.setStatus(SubmissionStatus.PENDING);

    logger.debug("Created new submission, id: {}", submission.getId());

    String notifyUrl = sandboxSubmissionProperties.getNotifyUrl();

    HttpEntity<MultiValueMap<String, Object>> requestEntity = buildRequestEntity(packaged,
        submission.getId().toString(), notifyUrl);

    SubmissionResponse response = restTemplate.postForObject("/tasks.json", requestEntity,
        SubmissionResponse.class);

    logger.debug("Received sandbox response: {}", response.getStatus());

    if (!response.getStatus().equals(SubmissionResponse.OK)) {
      logger.error("Sandbox submission failed!");
      return null;
    }

    submissionRepository.save(submission);

    return submission;
  }
}

@@ -50,16 +50,63 @@
 l.UUID;%0A
+import java.util.concurrent.CompletableFuture;%0A
 import o
@@ -118,24 +118,24 @@
 f4j.Logger;%0A
-
 import org.s
@@ -467,16 +467,72 @@
 iaType;%0A
+import org.springframework.scheduling.annotation.Async;%0A
 import o
@@ -819,57 +819,8 @@
 on;%0A
-import pingis.entities.sandbox.SubmissionStatus;%0A
 impo
@@ -1198,68 +1198,8 @@
 s;%0A%0A
-  private final SubmissionRepository submissionRepository;%0A%0A
   @A
@@ -1346,57 +1346,8 @@
 ties
-,%0A      SubmissionRepository submissionRepository
 ) %7B%0A
@@ -1417,62 +1417,8 @@
 ies;
-%0A    this.submissionRepository = submissionRepository;
 %0A%0A  
@@ -2243,23 +2243,50 @@
 %0A  %7D%0A%0A  
-public 
+@Async%0A  public CompletableFuture%3C
 Submissi
@@ -2287,16 +2287,25 @@
 bmission
+Response%3E
  sendSub
@@ -2358,61 +2358,8 @@
 ) %7B%0A
-    submission.setStatus(SubmissionStatus.PENDING);%0A%0A
     
@@ -2847,208 +2847,58 @@
     
-if (!response.getStatus().equals(SubmissionResponse.OK)) %7B%0A      logger.error(%22Sandbox submission failed!%22);%0A      return null;%0A    %7D%0A%0A    submissionRepository.save(submission);%0A%0A    return submission
+return CompletableFuture.completedFuture(response)
 ;%0A  

Make SubmissionSenderService async and remove SubmissionRepository.