/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.commons.scxml2.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

/**
 * The class in this SCXML object model that corresponds to the
 * &lt;transition&gt; SCXML element. Transition rules are triggered
 * by &quot;events&quot; and conditionalized via
 * &quot;guard-conditions&quot;.
 *
 */
public class Transition extends SimpleTransition implements DocumentOrder {

    /**
     * The document order of this transition
     */
    private int order;

    /**
     * Property that specifies the trigger(s) for this transition.
     */
    private String event;

    /**
     * This transition event descriptors
     */
    private List<String> events = Collections.emptyList();

    /**
     * Indicator for a event-less transition
     */
    private boolean noEvents;

    /**
     * Indicator for a transition matching all events (*)
     */
    private boolean allEvents;

    /**
     * Optional guard condition.
     */
    private String cond;

    /**
     * Constructor.
     */
    public Transition() {
    }


    /**
     * @return the document order of this transition
     * @see DocumentOrder
     */
    @Override
    public final int getOrder() {
        return order;
    }

    /**
     * Sets the document order of this transition
     * @param order the document order
     * @see DocumentOrder
     */
    public final void setOrder(int order) {
        this.order = order;
    }

    /**
     * Get the guard condition (may be null).
     *
     * @return Returns the cond.
     */
    public String getCond() {
        return cond;
    }

    /**
     * Set the guard condition.
     *
     * @param cond The cond to set.
     */
    public void setCond(final String cond) {
        this.cond = cond;
    }

    /**
     * Get the event that will trigger this transition (pending
     * evaluation of the guard condition in favor).
     *
     * @return Returns the event.
     */
    public String getEvent() {
        return event;
    }

    /**
     * Set the event that will trigger this transition (pending
     * evaluation of the guard condition in favor).
     *
     * @param event The event to set.
     */
    public void setEvent(final String event) {
        this.event = event == null ? null : event.trim();
        if (this.event != null) {
            // 'event' is a space separated list of event descriptors
            events = new ArrayList<>();
            StringTokenizer st = new StringTokenizer(this.event);
            while (st.hasMoreTokens()) {
                String token = st.nextToken();
                if (token.equals("*") || token.equals(".*")) {
                    events.clear();
                    events.add("*");
                    break;
                }
                else {
                    if (token.endsWith("*")) {
                        token = token.substring(0, token.length()-1);
                    }
                    if (token.endsWith(".")) {
                        token = token.substring(0, token.length()-1);
                    }
                    if (token.length() > 0) {
                        events.add(token);
                    }
                }
            }
        }
        else {
            events = Collections.emptyList();
        }
        noEvents = events.isEmpty();
        allEvents = !noEvents && events.get(0).equals("*");
    }

    /**
     * @return The list of this transition event descriptors
     */
    public final List<String> getEvents() {
        return events;
    }

    /**
     * @return True if this transition is event-less
     */
    public final boolean isNoEventsTransition() {
        return noEvents;
    }

    /**
     * @return True if this transition matches any events (*)
     */
    public final boolean isAllEventsTransition() {
        return allEvents;
    }
}
