/* (non-Javadoc)
   * @see org.ourgrid.broker.heuristic.Heuristic#verifyFailure(org.ourgrid.common.job.Task)
   */
  public boolean verifyFailure(Task task, GridProcessState state) {

    int actualFails = task.getActualFails();

    if (state.equals(GridProcessState.FAILED)) {
      actualFails++;
    }

    return actualFails >= maxFails && !task.hasGridProcessInExecution();
  }
  private boolean verifyTaskCanBeProcessed(Task task) {

    if (task.getActualFails() >= maxFails
        || task.hasFinishedReplica()
        || GridProcessState.CANCELLED.equals(task.getState())) {
      return false;
    }

    return true;
  }
  /**
   * Verifies if new <code>Replica</code>s can be scheduled for this
   *
   * @return <code>true</code> if it can.
   */
  public boolean canSchedule(Task task) {

    if (!verifyTaskCanBeProcessed(task)) {
      return false;
    }

    if (!task.hasRunnigGridProcess()) {
      return true;
    }

    if (task.getState().equals(GridProcessState.RUNNING) && task.getJob().hasUnallocatedTasks()) {
      return false;
    }

    return verifyRunningProccess(task);
  }
  private boolean verifyRunningProccess(Task task) {

    int running = 0;

    for (GridProcess replica : task.getGridProcesses()) {
      GridProcessState replicaState = replica.getState();

      if (GridProcessState.RUNNING.equals(replicaState)
          || GridProcessState.UNSTARTED.equals(replicaState)) {
        running++;
      }
    }

    return running < maxReplicas
        && (GridProcessState.RUNNING.equals(task.getState())
            || GridProcessState.UNSTARTED.equals(task.getState()));
  }
  private List<GetOperationTO> fillFinalGetOperations(
      List<ProcessCommand> list, Task task, int processId, String workerID, long requestId) {
    List<GetOperationTO> getOperationsList = new ArrayList<GetOperationTO>();

    for (ProcessCommand process : list) {

      GetOperationTO to = new GetOperationTO();
      to.setEndTime(process.getTransferEnd());
      to.setInitTime(process.getTransferBegin());
      to.setJobID(task.getJobId());
      to.setLocalFilePath(process.getFileName());
      to.setProcessID(processId);
      to.setRemoteFilePath(process.getDestination());
      to.setRequestID2(requestId);
      to.setTaskID(task.getTaskid());
      to.setTransferDescription(process.getHandle().getDescription());
      to.setWorkerID2(workerID);
      to.setFileSize(process.getFileSize());

      getOperationsList.add(to);
    }

    return getOperationsList;
  }
  private TaskStatusInfo fillTask(Task task) {

    List<GridProcessStatusInfo> processesList = new ArrayList<GridProcessStatusInfo>();

    for (GridProcess process : task.getGridProcesses()) {
      processesList.add(fillProcess(process));
    }

    TaskStatusInfo taskInfo =
        new TaskStatusInfo(
            task.getTaskid(),
            task.getJobId(),
            task.getState().toString(),
            task.getActualFails(),
            task.getSpec(),
            processesList,
            task.getCreationTime(),
            task.getFinalizationTime());

    return taskInfo;
  }
  private boolean createAndAllocateExecution(Job job, Task task, WorkerEntry chosenWorker) {

    GridProcess replica = null;
    if (canReplicate(task)) {
      replica = job.createAndAllocateExecution(task.getTaskid(), chosenWorker);
      replica.setRunningState(stateMachine.getInitialState());
    }

    if (replica != null) {
      chosenWorker.allocate(replica);

      WorkerEntry worker =
          WorkerInfo.getInstance()
              .getWorker(chosenWorker.getServiceID().getContainerID().toString());
      worker.allocate(replica);
      return true;
    }

    return false;
  }
  public JobWorkerStatus getCompleteStatus() {

    Map<Integer, Job> jobsMap = JobInfo.getInstance().getJobs();
    Map<Integer, Set<WorkerEntry>> workersByJob = CommonUtils.createMap();

    JobStatusInfo jobInfo = null;
    List<TaskStatusInfo> tasksList = null;
    Map<Integer, JobStatusInfo> jobs = CommonUtils.createSerializableMap();

    // Jobs
    for (Job job : jobsMap.values()) {
      Set<WorkerEntry> workers = new LinkedHashSet<WorkerEntry>();
      tasksList = new ArrayList<TaskStatusInfo>();

      for (Task task : job.getTasks()) {
        tasksList.add(fillTask(task));
        for (GridProcess gridProcess : task.getGridProcesses()) {
          if (gridProcess.getState() == GridProcessState.RUNNING)
            workers.add(gridProcess.getWorkerEntry());
        }
      }

      jobInfo =
          new JobStatusInfo(
              job.getJobId(),
              job.getSpec(),
              UtilConverter.getJobState(job.getState()),
              tasksList,
              job.getCreationTime(),
              job.getFinalizationTime());

      jobs.put(jobInfo.getJobId(), jobInfo);

      if (job.isRunning()) {
        workersByJob.put(job.getJobId(), workers);
      }
    }

    Map<Integer, WorkerStatusInfo[]> workers = CommonUtils.createSerializableMap();

    WorkerStatusInfo[] workerList = null;
    for (Entry<Integer, Set<WorkerEntry>> entry : workersByJob.entrySet()) {

      workerList = workers.get(entry.getKey());
      if (workerList == null) {
        workerList = new WorkerStatusInfo[entry.getValue().size()];
        workers.put(entry.getKey(), workerList);
      }

      int i = 0;
      for (WorkerEntry workerEntry : entry.getValue()) {

        GridProcessHandle handle = null;
        String state = null;

        if (workerEntry.getGridProcess() != null) {
          handle = workerEntry.getGridProcess().getHandle();
          state = workerEntry.getGridProcess().getState().toString();
        }

        workerList[i] =
            new WorkerStatusInfo(
                workerEntry.getWorkerSpecification(), handle, workerEntry.getWorkerID(), state);
        i++;
      }
    }

    JobWorkerStatus status = new JobWorkerStatus(jobs, workers);

    return status;
  }