// Path: src/main/java/com/github/fzakaria/waterflow/TaskType.java
// public enum TaskType {
//     ACTIVITY,
//     TIMER,
//     START_CHILD_WORKFLOW,
//     RECORD_MARKER,
//     SIGNAL_EXTERNAL_WORKFLOW,
//     CANCEL_EXTERNAL_WORKFLOW,
//     CONTINUE_AS_NEW,
//     DECISION,
//     WORKFLOW_EXECUTION,
//     WORKFLOW_SIGNALED
// }
// 
// Path: src/main/java/com/github/fzakaria/waterflow/TaskType.java
// public enum TaskType {
//     ACTIVITY,
//     TIMER,
//     START_CHILD_WORKFLOW,
//     RECORD_MARKER,
//     SIGNAL_EXTERNAL_WORKFLOW,
//     CANCEL_EXTERNAL_WORKFLOW,
//     CONTINUE_AS_NEW,
//     DECISION,
//     WORKFLOW_EXECUTION,
//     WORKFLOW_SIGNALED
// }
// 
// Path: src/main/java/com/github/fzakaria/waterflow/event/EventState.java
// public enum EventState {
// 
//     /**
//      * No events exist for the task.
//      */
//     NOT_STARTED,
// 
//     /**
//      * Initial event that started a task.
//      */
//     INITIAL,
// 
//     /**
//      * Event representing an ongoing task.
//      */
//     ACTIVE,
// 
//     /**
//      * Event representing a task that needs to be retried.
//      */
//     RETRY,
// 
//     /**
//      * Event representing a task that has completed successfully.
//      */
//     SUCCESS,
// 
//     /**
//      * Event representing a task that has failed.
//      */
//     ERROR
// }


import com.amazonaws.services.simpleworkflow.model.EventType;
import com.amazonaws.services.simpleworkflow.model.HistoryEvent;
import com.github.fzakaria.waterflow.TaskType;
import com.github.fzakaria.waterflow.immutable.ActionId;
import org.immutables.value.Value;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import static com.amazonaws.services.simpleworkflow.model.EventType.*;
import static com.github.fzakaria.waterflow.TaskType.*;
import static com.github.fzakaria.waterflow.event.EventState.*;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;
package com.github.fzakaria.waterflow.event;






/**
 * {@link Event} class consolidates SWF {@link HistoryEvent} types
 * so groups of similar event types can be accessed in a uniform way.
 */
@Value.Immutable
public abstract class Event implements Comparable<Event> {

    public abstract HistoryEvent historyEvent();

    /**
     * All history events are required since we need to find the previous events
     * they might refer to.
     */
    @Value.Auxiliary
    public abstract List<HistoryEvent> historyEvents();

    public static List<Event> fromHistoryEvents(List<HistoryEvent> historyEvents) {
        return historyEvents.stream()
                .map(h -> ImmutableEvent.builder().historyEvent(h).historyEvents(historyEvents).build())
                .sorted().collect(toList());
    }

    public EventType type() { return EventType.valueOf(historyEvent().getEventType()); }

    public Long id() { return historyEvent().getEventId(); }

    public Instant eventTimestamp() { return historyEvent().getEventTimestamp().toInstant(); }

// Path: src/main/java/com/github/fzakaria/waterflow/TaskType.java
// public enum TaskType {
//     ACTIVITY,
//     TIMER,
//     START_CHILD_WORKFLOW,
//     RECORD_MARKER,
//     SIGNAL_EXTERNAL_WORKFLOW,
//     CANCEL_EXTERNAL_WORKFLOW,
//     CONTINUE_AS_NEW,
//     DECISION,
//     WORKFLOW_EXECUTION,
//     WORKFLOW_SIGNALED
// }
// 
// Path: src/main/java/com/github/fzakaria/waterflow/TaskType.java
// public enum TaskType {
//     ACTIVITY,
//     TIMER,
//     START_CHILD_WORKFLOW,
//     RECORD_MARKER,
//     SIGNAL_EXTERNAL_WORKFLOW,
//     CANCEL_EXTERNAL_WORKFLOW,
//     CONTINUE_AS_NEW,
//     DECISION,
//     WORKFLOW_EXECUTION,
//     WORKFLOW_SIGNALED
// }
// 
// Path: src/main/java/com/github/fzakaria/waterflow/event/EventState.java
// public enum EventState {
// 
//     /**
//      * No events exist for the task.
//      */
//     NOT_STARTED,
// 
//     /**
//      * Initial event that started a task.
//      */
//     INITIAL,
// 
//     /**
//      * Event representing an ongoing task.
//      */
//     ACTIVE,
// 
//     /**
//      * Event representing a task that needs to be retried.
//      */
//     RETRY,
// 
//     /**
//      * Event representing a task that has completed successfully.
//      */
//     SUCCESS,
// 
//     /**
//      * Event representing a task that has failed.
//      */
//     ERROR
// }


// Path: src/main/java/com/github/fzakaria/waterflow/event/Event.java
import com.amazonaws.services.simpleworkflow.model.EventType;
import com.amazonaws.services.simpleworkflow.model.HistoryEvent;
import com.github.fzakaria.waterflow.TaskType;
import com.github.fzakaria.waterflow.immutable.ActionId;
import org.immutables.value.Value;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import static com.amazonaws.services.simpleworkflow.model.EventType.*;
import static com.github.fzakaria.waterflow.TaskType.*;
import static com.github.fzakaria.waterflow.event.EventState.*;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;

package com.github.fzakaria.waterflow.event;






/**
 * {@link Event} class consolidates SWF {@link HistoryEvent} types
 * so groups of similar event types can be accessed in a uniform way.
 */
@Value.Immutable
public abstract class Event implements Comparable<Event> {

    public abstract HistoryEvent historyEvent();

    /**
     * All history events are required since we need to find the previous events
     * they might refer to.
     */
    @Value.Auxiliary
    public abstract List<HistoryEvent> historyEvents();

    public static List<Event> fromHistoryEvents(List<HistoryEvent> historyEvents) {
        return historyEvents.stream()
                .map(h -> ImmutableEvent.builder().historyEvent(h).historyEvents(historyEvents).build())
                .sorted().collect(toList());
    }

    public EventType type() { return EventType.valueOf(historyEvent().getEventType()); }

    public Long id() { return historyEvent().getEventId(); }

    public Instant eventTimestamp() { return historyEvent().getEventTimestamp().toInstant(); }

    public TaskType task() {