/*
 * Copyright 2014-present Open Networking Laboratory
 *
 * 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.intent;

import com.google.common.annotations.Beta;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.NetworkResource;

import java.util.Collection;
import java.util.Objects;

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

/**
 * Abstraction of an application level intent.
 * <p>
 * Make sure that an Intent should be immutable when a new type is defined.
 * </p>
 */
@Beta
public abstract class Intent {

    private final IntentId id;

    private final ApplicationId appId;
    private final Key key;

    private final int priority;
    public static final int DEFAULT_INTENT_PRIORITY = 100;
    public static final int MAX_PRIORITY = (1 << 16) - 1;
    public static final int MIN_PRIORITY = 1;

    private final Collection<NetworkResource> resources;

    private static IdGenerator idGenerator;

    /**
     * Constructor for serializer.
     */
    protected Intent() {
        this.id = null;
        this.appId = null;
        this.key = null;
        this.resources = null;
        this.priority = DEFAULT_INTENT_PRIORITY;
    }

    /**
     * Creates a new intent.
     *
     * @param appId     application identifier
     * @param key       optional key
     * @param resources required network resources (optional)
     * @param priority  flow rule priority
     */
    protected Intent(ApplicationId appId,
                     Key key,
                     Collection<NetworkResource> resources,
                     int priority) {
        checkState(idGenerator != null, "Id generator is not bound.");
        checkArgument(priority <= MAX_PRIORITY && priority >= MIN_PRIORITY);
        this.id = IntentId.valueOf(idGenerator.getNewId());
        this.appId = checkNotNull(appId, "Application ID cannot be null");
        this.key = (key != null) ? key : Key.of(id.fingerprint(), appId);
        this.priority = priority;
        this.resources = checkNotNull(resources);
    }

    /**
     * Abstract builder for intents.
     */
    public abstract static class Builder {
        protected ApplicationId appId;
        protected Key key;
        protected int priority = Intent.DEFAULT_INTENT_PRIORITY;

        /**
         * Creates a new empty builder.
         */
        protected Builder() {
        }

        /**
         * Creates a new builder pre-populated with the information in the given
         * intent.
         *
         * @param intent initial intent
         */
        protected Builder(Intent intent) {
            this.appId(intent.appId())
                    .key(intent.key())
                    .priority(intent.priority());
        }

        /**
         * Sets the application id for the intent that will be built.
         *
         * @param appId application id to use for built intent
         * @return this builder
         */
        public Builder appId(ApplicationId appId) {
            this.appId = appId;
            return this;
        }

        /**
         * Sets the key for the intent that will be built.
         *
         * @param key key to use for built intent
         * @return this builder
         */
        public Builder key(Key key) {
            this.key = key;
            return this;
        }

        /**
         * Sets the priority for the intent that will be built.
         *
         * @param priority priority to use for built intent
         * @return this builder
         */
        public Builder priority(int priority) {
            this.priority = priority;
            return this;
        }

    }

    /**
     * Returns the intent identifier.
     *
     * @return intent fingerprint
     */
    public IntentId id() {
        return id;
    }

    /**
     * Returns the identifier of the application that requested the intent.
     *
     * @return application identifier
     */
    public ApplicationId appId() {
        return appId;
    }

    /**
     * Returns the priority of the intent.
     *
     * @return intent priority
     */
    public int priority() {
        return priority;
    }

    /**
     * Returns the collection of resources required for this intent.
     *
     * @return collection of resources; may be null
     */
    public Collection<NetworkResource> resources() {
        return resources;
    }

    /**
     * Indicates whether or not the intent is installable.
     *
     * @return true if installable
     */
    public boolean isInstallable() {
        return false;
    }

    @Override
    public final int hashCode() {
        return id.hashCode();
    }

    @Override
    public final boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        final Intent other = (Intent) obj;
        return this.id().equals(other.id());
    }

    /**
     * Binds an id generator for unique intent id generation.
     *
     * Note: A generator cannot be bound if there is already a generator bound.
     *
     * @param newIdGenerator id generator
     */
    public static void bindIdGenerator(IdGenerator newIdGenerator) {
        checkState(idGenerator == null, "Id generator is already bound.");
        idGenerator = checkNotNull(newIdGenerator);
    }

    /**
     * Unbinds an id generator.
     *
     * Note: The caller must provide the old id generator to succeed.
     *
     * @param oldIdGenerator the current id generator
     */
    public static void unbindIdGenerator(IdGenerator oldIdGenerator) {
        if (Objects.equals(idGenerator, oldIdGenerator)) {
            idGenerator = null;
        }
    }

    public Key key() {
        return key;
    }
}
