package edu.ipd.kit.crowdcontrol.proto.crowdplatform;

import com.amazonaws.mturk.requester.HIT;
import com.amazonaws.mturk.service.axis.RequesterService;
import com.amazonaws.mturk.util.ClientConfig;

import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * Created by marcel on 20.11.15.
 */
public class MTurkPlatform implements CrowdPlatform {
    private final String password;
    private final String username;
    private final String url;
    private ClientConfig config;
    private RequesterService service;

    public MTurkPlatform(String username, String password, String url) {
        this.password = password;
        this.username = username;
        this.url = url;

        config = new ClientConfig();
        config.setAccessKeyId(this.username);
        config.setSecretAccessKey(this.password);
        config.setServiceURL(this.url);

        service = new RequesterService(config);
    }

    @Override
    public CompletableFuture<Hit> publishTask(Hit hit) {
        String keywords = hit.getTags().stream()
                .collect(Collectors.joining(","));

        //30 days in seconds
        long assignment = 30*24*60*60;

        String question = "<?xml version=\"1.0\"?>\n<ExternalQuestion " +
                "xmlns=\"http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd\">" +
                "<ExternalURL>"+hit.getUrl()+"</ExternalURL>" +
                "<FrameHeight>200</FrameHeight>" +
                "</ExternalQuestion>";

        return CompletableFuture.supplyAsync(() -> {
            HIT hit1 = service.createHIT(hit.getTitle(), hit.getTitle(), hit.getDescription(), keywords, question, hit.getPayment(), hit.getAssignmentDuration(), assignment, hit.getHitDuration(), hit.getAmount(), null, null, null);
            Objects.requireNonNull(hit1);
            return hit;
        });
    }

    @Override
    public CompletableFuture<Hit> updateTask(Hit hit) {
        return CompletableFuture.supplyAsync(() -> {
            int assignmentIncrement = (int) (hit.getAssignmentDuration() - mhit.getAssignmentDurationInSeconds());

            if (increment < 0) {
                System.err.println("Assignment duration has to be bigger");
                throw new IllegalStateException("something wrong");
            }

            String keywords = hit.getTags().stream()
                    .collect(Collectors.joining(","));

            service.extendHIT(hit.getId(), assignmentIncrement, 0);
            //FIXME newhit
            service.updateHIT(hit.getId(), hit.getTitle(), hit.getDescription(), keywords, hit.getPayment());
            return hit;
        });
    }

    @Override
    public CompletableFuture<Hit> unpublishTask(Hit hit) {
        return unpublishTask(hit.getId()).thenApply(ignore -> hit);
    }

    /**
     * unpublish the task, after this call no answers can be sent for this task
     *
     * @param id
     * @return true if successful, false if not
     */
    @Override
    public CompletableFuture<String> unpublishTask(String id) {
        HIT mhit = service.getHIT(id);

        if (mhit == null) {
            //TODO: MARCEL: this is right?
            System.err.println("Hit is not published!");
            return CompletableFuture.completedFuture(id);
        }

        String[] hitids = {id};

        CompletableFuture<String> result = new CompletableFuture<>();
        service.deleteHITs(hitids, false, true, (o, b, o1, e) -> result.complete(id));
        return result;
    }

    @Override
    public CompletableFuture<Hit> payTask(Hit hit) {
        //
        return CompletableFuture.completedFuture(hit);
    }

    @Override
    public String getName() {
        return null;
    }
}

@@ -148,16 +148,79 @@
 ervice;%0A
+import com.amazonaws.mturk.service.exception.ServiceException;%0A
 import c
@@ -2114,32 +2114,129 @@
 lyAsync(() -%3E %7B%0A
+            HIT mhit = service.getHIT(hit.getId());%0A%0A            if (mhit == null) return null;%0A%0A
             int 
@@ -2351,17 +2351,27 @@
     if (
-i
+assignmentI
 ncrement
@@ -2638,32 +2638,54 @@
 joining(%22,%22));%0A%0A
+            try %7B%0A    
             serv
@@ -2731,16 +2731,23 @@
 crement,
+ (long)
  0);%0A   
@@ -2759,22 +2759,167 @@
     
-//FIXME newhit
+%7D catch (ServiceException e) %7B%0A                e.printStackTrace();%0A                return null;%0A            %7D%0A%0A            String id = null;%0A            try %7B
 %0A   
@@ -2918,32 +2918,41 @@
 ry %7B%0A           
+     id =
  service.updateH
@@ -3042,35 +3042,54 @@
             
-return hit;
+%7D catch (ServiceException e) %7B
 %0A        %7D);
@@ -3089,157 +3089,275 @@
     
-%7D);%0A
     
-%7D%0A%0A
     
-@Override%0A    public CompletableFuture%3CHit%3E unpublishTask(Hit hit) %7B%0A        return unpublishTask(hit.getId()).thenApply(ignore -%3E hit
+e.printStackTrace();%0A                return null;%0A            %7D%0A%0A            return new Hit(id, hit.getTitle(), hit.getDescription(), hit.getTags(), hit.getAmount(), hit.getPayment(), hit.getAssignmentDuration(), hit.getHitDuration(), hit.getUrl());%0A        %7D
 );%0A 

implement correct interface