/**
   * This will collect local data which is not synchronized and push them to the remote server
   *
   * @return
   */
  public static boolean execSendService(SyncServiceCallBack callBack) {
    List<Task> taskList = DAOFactory.getTaskDAO().getUnsynchronizedTaskList();
    if (taskList != null && !taskList.isEmpty()) {
      List<SharedTask> sharedTaskList = new LinkedList<SharedTask>();
      for (Task task : taskList) {
        sharedTaskList.add(Utils.toSharedData(task));
      }

      FreeDoitSendRequest fdsr = new FreeDoitSendRequest();
      fdsr.setTasks(sharedTaskList);

      // prepare json request data
      Gson retGson = FreeDoitDataUtils.createStandardJson();
      String message =
          retGson.toJson(
              fdsr, new com.google.gson.reflect.TypeToken<FreeDoitSendRequest>() {}.getType());

      System.out.println(message);

      callBack.before();
      String responseBody = Utils.sendHttpPostMessage(message, FreeDoitConfig.SEND_TASK_SERVICE);

      // parse response
      if (responseBody == null) {
        // callback
        if (callBack != null) {
          callBack.after(false);
        }
        return false;
      } else {
        System.out.println(responseBody);
        FreeDoitSyncDataResponse result =
            retGson.fromJson(
                responseBody,
                new com.google.gson.reflect.TypeToken<FreeDoitSyncDataResponse>() {}.getType());

        if (result.getCode() == FreeDoitSyncDataResponse.CODE_OK) {
          // Update local task object
          List<SharedTask> sharedTaskListResp = result.getTasks();
          if (sharedTaskListResp != null && !sharedTaskListResp.isEmpty()) {
            for (SharedTask task : sharedTaskListResp) {
              DAOFactory.getTaskDAO()
                  .updateTaskSynced(task.getSerialNo(), task.getTaskId(), result.getTimestamp());
            }

            // callback
            if (callBack != null) {
              callBack.after(true);
            }
            return true;
          } else {
            // callback
            if (callBack != null) {
              callBack.after(false);
            }
            return false;
          }

        } else {
          System.out.println("Code: " + result.getCode());
          // callback
          if (callBack != null) {
            callBack.after(false);
          }
          return false;
        }
      }
    } else {
      if (callBack != null) {
        callBack.after(true);
      }
      return true;
    }
  }
  public static int execSendReceiveService(SyncServiceCallBack callBack) {
    Long timestampKey = DAOFactory.getSyncKeyDAO().getKey();
    if (timestampKey == null) {
      timestampKey = FreeDoitDataUtils.NO_TIMESTAMP_KEY;
    }
    FreeDoitSendReceiveRequest fdsrr = new FreeDoitSendReceiveRequest(timestampKey);
    List<Task> taskList = DAOFactory.getTaskDAO().getUnsynchronizedTaskList();
    if (taskList != null && !taskList.isEmpty()) {
      List<SharedTask> sharedTaskList = new LinkedList<SharedTask>();
      for (Task task : taskList) {
        sharedTaskList.add(Utils.toSharedData(task));
      }

      fdsrr.setTasks(sharedTaskList);
    }

    // prepare json request data
    Gson retGson = FreeDoitDataUtils.createStandardJson();
    String message =
        retGson.toJson(
            fdsrr,
            new com.google.gson.reflect.TypeToken<FreeDoitSendReceiveRequest>() {}.getType());

    System.out.println(message);

    callBack.before();
    String responseBody =
        Utils.sendHttpPostMessage(message, FreeDoitConfig.SEND_RECEIVE_TASK_SERVICE);

    // parse response
    if (responseBody == null) {
      // callback
      if (callBack != null) {
        callBack.after(false);
      }
      return Constants.FAILURE;
    } else {
      System.out.println(responseBody);
      FreeDoitSendReceiveResponse result =
          retGson.fromJson(
              responseBody,
              new com.google.gson.reflect.TypeToken<FreeDoitSendReceiveResponse>() {}.getType());

      if (result.getCode() == FreeDoitSyncDataResponse.CODE_OK) {
        // Update local task object which is sent
        List<SharedTask> sharedTaskListResp = result.getSendTasks();
        if (sharedTaskListResp != null && !sharedTaskListResp.isEmpty()) {
          for (SharedTask task : sharedTaskListResp) {
            DAOFactory.getTaskDAO()
                .updateTaskSynced(task.getSerialNo(), task.getTaskId(), result.getTimestamp());
          }
        }

        // Update local task object
        int taskReceive = 0;
        sharedTaskListResp = result.getReceiveTasks();
        if (sharedTaskListResp != null && (taskReceive = sharedTaskListResp.size()) > 0) {
          Task task = null;

          // Update Task Received
          for (SharedTask sharedTask : sharedTaskListResp) {
            task = Utils.fromSharedData(sharedTask);
            task.setLastModifyTime(result.getTimestamp());
            task.setSynced(true);
            DAOFactory.getTaskDAO().saveOrUpdate(task);
          }
        }
        // Update local project object
        List<SharedProject> sharedProjectListResp = result.getReceiveProjects();
        if (sharedProjectListResp != null && !sharedProjectListResp.isEmpty()) {
          Project project = null;

          // Update Task Received
          for (SharedProject sharedProject : sharedProjectListResp) {
            project =
                new Project(
                    sharedProject.getProjectId(),
                    sharedProject.getProjectName(),
                    sharedProject.getComment(),
                    sharedProject.getCreateDate(),
                    sharedProject.getStartDate(),
                    sharedProject.getDueDate(),
                    result.getTimestamp(),
                    sharedProject.getStatus());

            project.setSynced(true);

            DAOFactory.getProjectDAO().saveOrUpdate(project);
            // DAOFactory.getTaskDAO().update(task);
          }
        }
        // Update local task type object
        //                List<SharedTaskType> sharedTaskTypeListResp =
        // result.getReceiveTaskTypes();
        //                if (sharedTaskTypeListResp != null && !sharedTaskTypeListResp.isEmpty()) {
        //                    TaskType taskType = null;
        //
        //                    // Update Task Received
        //                    for (SharedTaskType sharedTaskType : sharedTaskTypeListResp) {
        //                        taskType = new TaskType(sharedTaskType.getTaskTypeId(),
        // sharedTaskType.getTaskTypeName(),
        //                                sharedTaskType.getTaskTypeDescrition(),
        // sharedTaskType.getStatus(), result.getTimestamp());
        //                        taskType.setLastModifyTime(result.getTimestamp());
        //                        DAOFactory.getTaskTypeDAO().persist(taskType);
        //                    }
        //                }

        // Update local synchronize key
        DAOFactory.getSyncKeyDAO().setKey(result.getTimestamp());

        System.out.println(DAOFactory.getSyncKeyDAO().getKey());

        // callback
        if (callBack != null) {
          callBack.after(true);
        }
        return taskReceive;

      } else {
        System.out.println("Code: " + result.getCode());
        // callback
        if (callBack != null) {
          callBack.after(false);
        }
        return Constants.FAILURE;
      }
    }
  }