package org.zstack.header.core;

import org.zstack.header.errorcode.ErrorCode;
import org.zstack.header.errorcode.SysErrors;
import org.zstack.header.exception.CloudRuntimeException;

import java.util.concurrent.TimeUnit;

/**
 */
public class FutureCompletion extends Completion {
    private volatile boolean success;
    private ErrorCode errorCode;
    private volatile boolean done;
    private boolean timeout;

    public boolean isTimeout() {
        return timeout;
    }

    public void setTimeout(boolean timeout) {
        this.timeout = timeout;
    }

    public FutureCompletion(AsyncBackup one, AsyncBackup... others) {
        super(one, others);
    }

    @Override
    public final synchronized void success() {
        this.success = true;
        done = true;
        notifyAll();
    }

    @Override
    public synchronized void fail(ErrorCode errorCode) {
        this.success = false;
        this.errorCode = errorCode;
        done = true;
        notifyAll();
    }

    public boolean isSuccess() {
        return success;
    }

    public ErrorCode getErrorCode() {
        return errorCode;
    }

    public synchronized void await(long timeout) {
        if (done) {
            return;
        }

        try {
            wait(timeout);
        } catch (InterruptedException e) {
            throw new CloudRuntimeException(e);
        }

        if (!done) {
            this.timeout = true;
            ErrorCode err = new ErrorCode();
            err.setCode(SysErrors.TIMEOUT.toString());
            err.setDetails(String.format("FutureCompletion timeout after %s seconds", TimeUnit.MILLISECONDS.toSeconds(timeout)));
            fail(err);
        }
    }

    public synchronized void await() {
        if (done) {
            return;
        }

        try {
            wait();
        } catch (InterruptedException e) {
            throw new CloudRuntimeException(e);
        }
    }
}

@@ -1239,141 +1239,24 @@
     
-try %7B%0A            wait(timeout);%0A        %7D catch (InterruptedException e) %7B%0A            throw new CloudRuntimeException(e);%0A        %7D
+doWait(timeout);
 %0A%0A  
@@ -1533,24 +1533,24 @@
 timeout)));%0A
-
             
@@ -1569,32 +1569,452 @@
        %7D%0A    %7D%0A%0A
+    public synchronized boolean tryWait(long timeout) %7B%0A        if (done) %7B%0A            return done;%0A        %7D%0A%0A        doWait(timeout);%0A%0A        if (!done) %7B%0A            this.timeout = true;%0A        %7D%0A%0A        return done;%0A    %7D%0A%0A    private void doWait(long timeout) %7B%0A        try %7B%0A            wait(timeout);%0A        %7D catch (InterruptedException e) %7B%0A            throw new CloudRuntimeException(e);%0A        %7D%0A    %7D%0A%0A
     public synch

add tryWait for FutureCompletion