package org.bdgp.MMSlide.DB;

import java.io.File;

import org.bdgp.MMSlide.Util;

import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;

/**
 * Task metadata storage. For each task instance, store the
 * storage location path and the status.
 */
@DatabaseTable
public class Task {
    public Task() {}
    public Task(String moduleId, Status status) {
       this.moduleId = moduleId;
       this.status = status;
    }
    public Task(String moduleId, String storageLocation, Status status) {
       this.moduleId = moduleId;
       this.storageLocation = storageLocation;
       this.status = status;
    }
    public String toString() {
    	return String.format("%s(id=%d, parentTaskId=%d, moduleId=%s, storageLocation=%s, status=%s)", 
    			this.getName(), 
    			this.id, this.parentTaskId, Util.escape(moduleId), Util.escape(storageLocation), status);
    }
    
    @DatabaseField(generatedId=true,canBeNull=false)
    private int id;

    // This field is used by the workflow runner task dispatching logic to determine
    // which parent task should dispatch a child task in cases where a child task 
    // has multiple parent tasks. It is not the same as the TaskDispatch.parentTaskId, 
    // which describes the task DAG.
    @DatabaseField(canBeNull=true)
    private Integer parentTaskId;
    
    @DatabaseField(canBeNull=false,dataType=DataType.LONG_STRING)
    private String moduleId;
    
    @DatabaseField(canBeNull=true,dataType=DataType.LONG_STRING)
    private String storageLocation;
    
    public static enum Status {ERROR, FAIL, SUCCESS, IN_PROGRESS, DEFER, NEW};
    
    @DatabaseField(canBeNull=false)
    private Status status;
    
    public int getId() {
        return id;
    }
    public Integer getParentTaskId() { 
    	return this.parentTaskId; 
    }
    public Status getStatus() {
        return status;
    }
    public String getStorageLocation() {
        return storageLocation;
    }
    public String createStorageLocation(String parent, String toplevel) {
        // create a new directory for the task instance
    	File dir = parent != null? new File(parent, this.getName()) : new File(this.getName());
        File path = new File(toplevel, dir.getPath());
        if (!path.exists() && !path.mkdirs()) {
            throw new RuntimeException("Could not create directory "+path.toString());
        }
        this.storageLocation = dir.toString();
        return this.storageLocation;
    }
    public String getModuleId() {
        return moduleId;
    }
    public void setStatus(Status status) {
        this.status = status;
    }
    public String getName() { 
        return String.format("%s.T%05d",this.moduleId,this.id); 
    }
};

@@ -2769,11 +2769,1239 @@
  %0A    %7D%0A
+%09@Override%0A%09public int hashCode() %7B%0A%09%09final int prime = 31;%0A%09%09int result = 1;%0A%09%09result = prime * result + id;%0A%09%09result = prime * result%0A%09%09%09%09+ ((moduleId == null) ? 0 : moduleId.hashCode());%0A%09%09result = prime * result%0A%09%09%09%09+ ((parentTaskId == null) ? 0 : parentTaskId.hashCode());%0A%09%09result = prime * result + ((status == null) ? 0 : status.hashCode());%0A%09%09result = prime * result%0A%09%09%09%09+ ((storageLocation == null) ? 0 : storageLocation.hashCode());%0A%09%09return result;%0A%09%7D%0A%09@Override%0A%09public boolean equals(Object obj) %7B%0A%09%09if (this == obj)%0A%09%09%09return true;%0A%09%09if (obj == null)%0A%09%09%09return false;%0A%09%09if (getClass() != obj.getClass())%0A%09%09%09return false;%0A%09%09Task other = (Task) obj;%0A%09%09if (id != other.id)%0A%09%09%09return false;%0A%09%09if (moduleId == null) %7B%0A%09%09%09if (other.moduleId != null)%0A%09%09%09%09return false;%0A%09%09%7D else if (!moduleId.equals(other.moduleId))%0A%09%09%09return false;%0A%09%09if (parentTaskId == null) %7B%0A%09%09%09if (other.parentTaskId != null)%0A%09%09%09%09return false;%0A%09%09%7D else if (!parentTaskId.equals(other.parentTaskId))%0A%09%09%09return false;%0A%09%09if (status != other.status)%0A%09%09%09return false;%0A%09%09if (storageLocation == null) %7B%0A%09%09%09if (other.storageLocation != null)%0A%09%09%09%09return false;%0A%09%09%7D else if (!storageLocation.equals(other.storageLocation))%0A%09%09%09return false;%0A%09%09return true;%0A%09%7D%0A
 %7D;%0A

add hashCode and equals so we can make a set of Tasks