// Path: lib/src/main/java/com/github/niqdev/openwebnet/OpenSession.java
// public class OpenSession {
// 
//     private final OpenMessage request;
//     private final List<OpenMessage> response = new ArrayList<>();
// 
//     private OpenSession(OpenMessage request) {
//         checkNotNull(request, "request can't be null");
//         this.request = request;
//     }
// 
//     /**
//      * Helper method to create a new session.
//      *
//      * @param request message
//      * @return session
//      */
//     public static OpenSession newSession(OpenMessage request) {
//         return new OpenSession(request);
//     }
// 
//     /**
//      * Update the response messages.
//      *
//      * @param response messages
//      * @return session
//      */
//     public OpenSession addAllResponse(List<OpenMessage> response) {
//         checkNotNull(response, "response can't be null");
//         this.response.addAll(response);
//         return this;
//     }
// 
//     /**
//      * Update the response messages.
//      *
//      * @param response messages
//      * @return session
//      */
//     public OpenSession addResponse(OpenMessage response) {
//         checkNotNull(response, "response can't be null");
//         this.response.add(response);
//         return this;
//     }
// 
//     /**
//      * Returns the initial request message.
//      *
//      * @return request
//      */
//     public OpenMessage getRequest() {
//         return request;
//     }
// 
//     /**
//      * Returns the response messages.
//      *
//      * @return response
//      */
//     public List<OpenMessage> getResponse() {
//         return response;
//     }
// 
//     @Override
//     public String toString() {
//         return MoreObjects.toStringHelper(this)
//             .add("request", request.getValue())
//             .add("response", response)
//             .toString();
//     }
// }


import com.github.niqdev.openwebnet.OpenSession;
import com.google.common.collect.FluentIterable;
import rx.functions.Action0;
import rx.functions.Func1;
import java.util.List;
import static com.github.niqdev.openwebnet.message.Who.SCENARIO_PROGRAMMING;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
package com.github.niqdev.openwebnet.message;




/**
 * OpenWebNet Scenario.
 *
 * <pre>
 * {@code
 *
 * import static com.github.niqdev.openwebnet.OpenWebNet.defaultGateway;
 *
 * OpenWebNet client = OpenWebNet.newClient(defaultGateway("IP_ADDRESS"));
 *
 * // start scenario 31
 * client
 *    .send(Scenario.requestStart("31", Scenario.Version.MH200N))
 *    .map(Scenario.handleResponse(() -> System.out.println("START"), () -> System.out.println("STOP")))
 *    .subscribe(System.out::println);
 *
 * // requests status scenario 31
 * client
 *    .send(Scenario.requestStatus("31"))
 *    .map(Scenario.handleStatus(
 *       () -> System.out.println("STARTED"),
 *       () -> System.out.println("STOPPED"),
 *       () -> System.out.println("ENABLED"),
 *       () -> System.out.println("DISABLED")))
*     .subscribe(System.out::println);
 * }
 * </pre>
 */
public class Scenario extends BaseOpenMessage {

    private static final int START = 1;
    private static final int STOP = 2;
    private static final int ENABLE = 3;
    private static final int DISABLE = 4;
    private static final int WHO = SCENARIO_PROGRAMMING.value();

    public enum Version {
        // 0-300
        MH200N,
        // numeric 0-9999
        MH202
    }

    private Scenario(String value) {
        super(value);
    }

    /**
     * OpenWebNet message request to send the <i>START</i> scenario command with value <b>*17*1*WHERE##</b>.
     *
     * @param where Value between 0 and 9999
     * @return message
     */
    public static Scenario requestStart(String where) {
        checkRange(WHERE_MIN_VALUE, WHERE_MAX_VALUE, checkIsInteger(where));
        return new Scenario(format(FORMAT_REQUEST, WHO, START, where));
    }

    /**
     * OpenWebNet message request to send the <i>START</i> scenario command with value <b>*17*1*WHERE##</b>.
     *
     * @param where Value between 0 and 300 if MH200N or 0 and 9999 if MH202
     * @param version MH200N or MH202
     * @return message
     */
    public static Scenario requestStart(String where, Version version) {
        checkRangeVersion(where, version);
        return new Scenario(format(FORMAT_REQUEST, WHO, START, where));
    }

    /**
     * OpenWebNet message request to send the <i>STOP</i> scenario command with value <b>*17*2*WHERE##</b>.
     *
     * @param where Value between 0 and 9999
     * @return message
     */
    public static Scenario requestStop(String where) {
        checkRange(WHERE_MIN_VALUE, WHERE_MAX_VALUE, checkIsInteger(where));
        return new Scenario(format(FORMAT_REQUEST, WHO, STOP, where));
    }

    /**
     * OpenWebNet message request to send the <i>STOP</i> scenario command with value <b>*17*2*WHERE##</b>.
     *
     * @param where Value between 0 and 300 if MH200N or 0 and 9999 if MH202
     * @param version MH200N or MH202
     * @return message
     */
    public static Scenario requestStop(String where, Version version) {
        checkRangeVersion(where, version);
        return new Scenario(format(FORMAT_REQUEST, WHO, STOP, where));
    }

    /**
     * Handle response from {@link Scenario#requestStart(String)} and {@link Scenario#requestStop(String)}.
     *
     * @param onSuccess invoked if the request has been successfully received
     * @param onFail    invoked otherwise
     * @return {@code Observable<OpenSession>}
     */
// Path: lib/src/main/java/com/github/niqdev/openwebnet/OpenSession.java
// public class OpenSession {
// 
//     private final OpenMessage request;
//     private final List<OpenMessage> response = new ArrayList<>();
// 
//     private OpenSession(OpenMessage request) {
//         checkNotNull(request, "request can't be null");
//         this.request = request;
//     }
// 
//     /**
//      * Helper method to create a new session.
//      *
//      * @param request message
//      * @return session
//      */
//     public static OpenSession newSession(OpenMessage request) {
//         return new OpenSession(request);
//     }
// 
//     /**
//      * Update the response messages.
//      *
//      * @param response messages
//      * @return session
//      */
//     public OpenSession addAllResponse(List<OpenMessage> response) {
//         checkNotNull(response, "response can't be null");
//         this.response.addAll(response);
//         return this;
//     }
// 
//     /**
//      * Update the response messages.
//      *
//      * @param response messages
//      * @return session
//      */
//     public OpenSession addResponse(OpenMessage response) {
//         checkNotNull(response, "response can't be null");
//         this.response.add(response);
//         return this;
//     }
// 
//     /**
//      * Returns the initial request message.
//      *
//      * @return request
//      */
//     public OpenMessage getRequest() {
//         return request;
//     }
// 
//     /**
//      * Returns the response messages.
//      *
//      * @return response
//      */
//     public List<OpenMessage> getResponse() {
//         return response;
//     }
// 
//     @Override
//     public String toString() {
//         return MoreObjects.toStringHelper(this)
//             .add("request", request.getValue())
//             .add("response", response)
//             .toString();
//     }
// }


// Path: lib/src/main/java/com/github/niqdev/openwebnet/message/Scenario.java
import com.github.niqdev.openwebnet.OpenSession;
import com.google.common.collect.FluentIterable;
import rx.functions.Action0;
import rx.functions.Func1;
import java.util.List;
import static com.github.niqdev.openwebnet.message.Who.SCENARIO_PROGRAMMING;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;

package com.github.niqdev.openwebnet.message;




/**
 * OpenWebNet Scenario.
 *
 * <pre>
 * {@code
 *
 * import static com.github.niqdev.openwebnet.OpenWebNet.defaultGateway;
 *
 * OpenWebNet client = OpenWebNet.newClient(defaultGateway("IP_ADDRESS"));
 *
 * // start scenario 31
 * client
 *    .send(Scenario.requestStart("31", Scenario.Version.MH200N))
 *    .map(Scenario.handleResponse(() -> System.out.println("START"), () -> System.out.println("STOP")))
 *    .subscribe(System.out::println);
 *
 * // requests status scenario 31
 * client
 *    .send(Scenario.requestStatus("31"))
 *    .map(Scenario.handleStatus(
 *       () -> System.out.println("STARTED"),
 *       () -> System.out.println("STOPPED"),
 *       () -> System.out.println("ENABLED"),
 *       () -> System.out.println("DISABLED")))
*     .subscribe(System.out::println);
 * }
 * </pre>
 */
public class Scenario extends BaseOpenMessage {

    private static final int START = 1;
    private static final int STOP = 2;
    private static final int ENABLE = 3;
    private static final int DISABLE = 4;
    private static final int WHO = SCENARIO_PROGRAMMING.value();

    public enum Version {
        // 0-300
        MH200N,
        // numeric 0-9999
        MH202
    }

    private Scenario(String value) {
        super(value);
    }

    /**
     * OpenWebNet message request to send the <i>START</i> scenario command with value <b>*17*1*WHERE##</b>.
     *
     * @param where Value between 0 and 9999
     * @return message
     */
    public static Scenario requestStart(String where) {
        checkRange(WHERE_MIN_VALUE, WHERE_MAX_VALUE, checkIsInteger(where));
        return new Scenario(format(FORMAT_REQUEST, WHO, START, where));
    }

    /**
     * OpenWebNet message request to send the <i>START</i> scenario command with value <b>*17*1*WHERE##</b>.
     *
     * @param where Value between 0 and 300 if MH200N or 0 and 9999 if MH202
     * @param version MH200N or MH202
     * @return message
     */
    public static Scenario requestStart(String where, Version version) {
        checkRangeVersion(where, version);
        return new Scenario(format(FORMAT_REQUEST, WHO, START, where));
    }

    /**
     * OpenWebNet message request to send the <i>STOP</i> scenario command with value <b>*17*2*WHERE##</b>.
     *
     * @param where Value between 0 and 9999
     * @return message
     */
    public static Scenario requestStop(String where) {
        checkRange(WHERE_MIN_VALUE, WHERE_MAX_VALUE, checkIsInteger(where));
        return new Scenario(format(FORMAT_REQUEST, WHO, STOP, where));
    }

    /**
     * OpenWebNet message request to send the <i>STOP</i> scenario command with value <b>*17*2*WHERE##</b>.
     *
     * @param where Value between 0 and 300 if MH200N or 0 and 9999 if MH202
     * @param version MH200N or MH202
     * @return message
     */
    public static Scenario requestStop(String where, Version version) {
        checkRangeVersion(where, version);
        return new Scenario(format(FORMAT_REQUEST, WHO, STOP, where));
    }

    /**
     * Handle response from {@link Scenario#requestStart(String)} and {@link Scenario#requestStop(String)}.
     *
     * @param onSuccess invoked if the request has been successfully received
     * @param onFail    invoked otherwise
     * @return {@code Observable<OpenSession>}
     */
    public static Func1<OpenSession, OpenSession> handleResponse(Action0 onSuccess, Action0 onFail) {