/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.
 */

package org.onosproject.net.pi.runtime;

import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

import java.util.Collection;
import java.util.Map;
import java.util.StringJoiner;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Instance of an action, and its runtime parameters, of a table entry in a protocol-independent
 * pipeline.
 */
@Beta
public final class PiAction implements PiTableAction {

    private final PiActionId actionId;
    private final Map<PiActionParamId, PiActionParam> runtimeParams;

    /**
     * Creates a new action instance for the given action identifier and runtime parameters.
     *
     * @param actionId      action identifier
     * @param runtimeParams list of runtime parameters
     */
    private PiAction(PiActionId actionId, Map<PiActionParamId, PiActionParam> runtimeParams) {
        this.actionId = actionId;
        this.runtimeParams = ImmutableMap.copyOf(runtimeParams);
    }

    @Override
    public Type type() {
        return Type.ACTION;
    }

    /**
     * Return the identifier of this action.
     *
     * @return action identifier
     */
    public PiActionId id() {
        return actionId;
    }

    /**
     * Returns all runtime parameters of this action.
     * Return an empty collection if the action doesn't take any runtime parameters.
     *
     * @return list of byte sequences
     */
    public Collection<PiActionParam> parameters() {
        return runtimeParams.values();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        PiAction piAction = (PiAction) o;
        return Objects.equal(actionId, piAction.actionId) &&
                Objects.equal(runtimeParams, piAction.runtimeParams);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(actionId, runtimeParams);
    }

    @Override
    public String toString() {
        StringJoiner stringParams = new StringJoiner(", ", "(", ")");
        this.parameters().forEach(p -> stringParams.add(p.toString()));
        return MoreObjects.toStringHelper(this)
                .addValue(this.id().toString() + stringParams.toString())
                .toString();
    }

    /**
     * Returns an action builder.
     *
     * @return a new builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Builder of protocol-independent actions.
     */
    public static final class Builder {

        private PiActionId actionId;
        private Map<PiActionParamId, PiActionParam> runtimeParams = Maps.newHashMap();

        private Builder() {
            // hides constructor.
        }

        /**
         * Sets the identifier of this action.
         *
         * @param actionId action identifier
         * @return this
         */
        public Builder withId(PiActionId actionId) {
            this.actionId = actionId;
            return this;
        }

        /**
         * Adds a runtime parameter.
         *
         * @param param action parameter
         * @return this
         */
        public Builder withParameter(PiActionParam param) {
            checkNotNull(param);
            runtimeParams.put(param.id(), param);
            return this;
        }

        /**
         * Adds many runtime parameters.
         *
         * @param params collection of action parameters
         * @return this
         */
        public Builder withParameters(Collection<PiActionParam> params) {
            checkNotNull(params);
            params.forEach(this::withParameter);
            return this;
        }

        /**
         * Returns a new action instance.
         *
         * @return action
         */
        public PiAction build() {
            checkNotNull(actionId);
            return new PiAction(actionId, runtimeParams);
        }
    }
}
