/*
 * Copyright 2015-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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

/**
 * Utilities for dealing with intents.
 */
public final class IntentUtils {

    private static final Logger log = LoggerFactory.getLogger(IntentUtils.class);

    private IntentUtils() {
    }

    /**
     * Checks if two intents represent the same value.
     *
     * <p>({@link Intent#equals(Object)} only checks ID equality)</p>
     *
     * <p>Both intents must be of the same type.</p>
     *
     * @param one first intent
     * @param two second intent
     * @return true if the two intents represent the same value, otherwise false
     */
    public static boolean intentsAreEqual(Intent one, Intent two) {
        if (one.getClass() != two.getClass()) {
            return false;
        }

        if (!(Objects.equals(one.appId(), two.appId()) &&
                Objects.equals(one.key(), two.key()))) {
            return false;
        }

        if (one instanceof SinglePointToMultiPointIntent) {
            SinglePointToMultiPointIntent intent1 = (SinglePointToMultiPointIntent) one;
            SinglePointToMultiPointIntent intent2 = (SinglePointToMultiPointIntent) two;

            return Objects.equals(intent1.selector(), intent2.selector()) &&
                    Objects.equals(intent1.treatment(), intent2.treatment()) &&
                    Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
                    Objects.equals(intent1.egressPoints(), intent2.egressPoints());
        } else if (one instanceof MultiPointToSinglePointIntent) {
            MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one;
            MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two;

            return Objects.equals(intent1.selector(), intent2.selector()) &&
                    Objects.equals(intent1.treatment(), intent2.treatment()) &&
                    Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) &&
                    Objects.equals(intent1.egressPoint(), intent2.egressPoint());
        } else if (one instanceof PointToPointIntent) {
            PointToPointIntent intent1 = (PointToPointIntent) one;
            PointToPointIntent intent2 = (PointToPointIntent) two;

            return Objects.equals(intent1.selector(), intent2.selector()) &&
                    Objects.equals(intent1.treatment(), intent2.treatment()) &&
                    Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
                    Objects.equals(intent1.egressPoint(), intent2.egressPoint());
        } else {
            log.error("Unimplemented intent type");
            return false;
        }
    }
}
