package com.inmobi.grill.api.query;

/*
 * #%L
 * Grill API
 * %%
 * Copyright (C) 2014 Inmobi
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.io.Serializable;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Setter;

@XmlRootElement
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class QueryStatus implements Serializable {
  private static final long serialVersionUID = 1L;

  public enum Status {
    NEW,
    QUEUED,
    LAUNCHED,
    RUNNING,
    SUCCESSFUL,
    FAILED,
    CANCELED,
    CLOSED
  }
  
  @XmlElement @Getter private double progress;
  @XmlElement @Getter private Status status;
  @XmlElement @Getter private String statusMessage;
  @XmlElement @Getter private boolean isResultSetAvailable = false;
  @Getter @Setter private String progressMessage;
  @Getter @Setter private String errorMessage;

  @Override
  public String toString() {
  	return new StringBuilder(status.toString()).append(':')
  			.append(progress).append(':')
  			.append(isResultSetAvailable).append(':').
  			append(statusMessage).toString();
  }

  public boolean isFinished() {
    return status.equals(Status.SUCCESSFUL) || status.equals(Status.FAILED) ||
        status.equals(Status.CANCELED);
  }

  public static boolean isValidTransition(Status oldState, Status newState) {
    switch (oldState) {
    case NEW:
      switch (newState) {
      case QUEUED:
        return true;
      }
      break;
    case QUEUED:
      switch (newState) {
      case LAUNCHED:
      case FAILED:
      case CANCELED:
        return true;
      }
      break;
    case LAUNCHED:
      switch (newState) {
      case LAUNCHED:
      case RUNNING:
      case CANCELED:
      case FAILED:
      case SUCCESSFUL:
        return true;
      }
      break;
    case RUNNING:
      switch (newState) {
      case RUNNING:
      case CANCELED:
      case FAILED:
      case SUCCESSFUL:
        return true;
      }
      break;
    case FAILED:
    case CANCELED:
    case SUCCESSFUL:
      if (Status.CLOSED.equals(newState)) {
        return true;
      }
    default:
      // fall-through
    }
    return false;
  }

  public boolean isValidateTransition(Status newState) {
    return isValidTransition(this.status, newState);
  }

}

@@ -1603,22 +1603,35 @@
 () %7B%0A  %09
-return
+StringBuilder str =
  new Str
@@ -1675,118 +1675,471 @@
 ':')
+.
 %0A  
-%09%09%09.append(progress).append(':')%0A  %09%09%09.append(isResultSetAvailable).append(':').%0A  %09%09%09append(statusMessage)
+  append(statusMessage);%0A  %09if (status.equals(Status.RUNNING)) %7B%0A  %09  str.append(%22 - Progress:%22).append(progress).append(%22:%22).append(progressMessage);%0A  %09%7D%0A  %09if (status.equals(Status.SUCCESSFUL)) %7B%0A  %09  if (isResultSetAvailable) %7B%0A  %09    str.append(%22 - Result Available%22);%0A  %09  %7D else %7B%0A        str.append(%22 - Result Not Available%22);%0A  %09  %7D%0A  %09%7D%0A    if (status.equals(Status.FAILED)) %7B%0A      str.append(%22 - Cause:%22).append(errorMessage);%0A    %7D%0A    return str
 .toS

Format status string