/*
 * Copyright 2021-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.kubevirtnetworking.codec;

import com.fasterxml.jackson.databind.JsonNode;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.onosproject.kubevirtnetworking.api.KubevirtHostRoute;
import org.onosproject.kubevirtnetworking.api.KubevirtIpPool;
import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;

/**
 * Hamcrest matcher for kubevirt network.
 */
public final class KubevirtNetworkJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {

    private final KubevirtNetwork network;
    private static final String NETWORK_ID = "networkId";
    private static final String TYPE = "type";
    private static final String NAME = "name";
    private static final String MTU = "mtu";
    private static final String SEGMENT_ID = "segmentId";
    private static final String GATEWAY_IP = "gatewayIp";
    private static final String CIDR = "cidr";
    private static final String HOST_ROUTES = "hostRoutes";
    private static final String IP_POOL = "ipPool";

    private KubevirtNetworkJsonMatcher(KubevirtNetwork network) {
        this.network = network;
    }

    @Override
    protected boolean matchesSafely(JsonNode jsonNode, Description description) {
        // check network ID
        String jsonNetworkId = jsonNode.get(NETWORK_ID).asText();
        String networkId = network.networkId();
        if (!jsonNetworkId.equals(networkId)) {
            description.appendText("network ID was " + jsonNetworkId);
            return false;
        }

        // check type
        String jsonType = jsonNode.get(TYPE).asText();
        String type = network.type().name();
        if (!jsonType.equals(type)) {
            description.appendText("network type was " + jsonType);
            return false;
        }

        // check name
        String jsonName = jsonNode.get(NAME).asText();
        String name = network.name();
        if (!jsonName.equals(name)) {
            description.appendText("network name was " + jsonName);
            return false;
        }

        // check MTU
        int jsonMtu = jsonNode.get(MTU).asInt();
        int mtu = network.mtu();
        if (jsonMtu != mtu) {
            description.appendText("network MTU was " + jsonMtu);
            return false;
        }

        // check gateway IP
        String jsonGatewayIp = jsonNode.get(GATEWAY_IP).asText();
        String gatewayIp = network.gatewayIp().toString();
        if (!jsonGatewayIp.equals(gatewayIp)) {
            description.appendText("gateway IP was " + jsonGatewayIp);
            return false;
        }

        // check CIDR
        String jsonCidr = jsonNode.get(CIDR).asText();
        String cidr = network.cidr();
        if (!jsonCidr.equals(cidr)) {
            description.appendText("CIDR was " + jsonCidr);
            return false;
        }

        // check segment ID
        JsonNode jsonSegmentId = jsonNode.get(SEGMENT_ID);
        if (jsonSegmentId != null) {
            String segmentId = network.segmentId();
            if (!jsonSegmentId.asText().equals(segmentId)) {
                description.appendText("segment ID was " + jsonSegmentId.asText());
                return false;
            }
        }

        // check ip pool
        JsonNode jsonIpPool = jsonNode.get(IP_POOL);
        if (jsonIpPool != null) {
            KubevirtIpPool ipPool = network.ipPool();
            KubevirtIpPoolJsonMatcher ipPoolMatcher =
                    KubevirtIpPoolJsonMatcher.matchesKubevirtIpPool(ipPool);
            if (ipPoolMatcher.matches(jsonIpPool)) {
                return true;
            } else {
                description.appendText("IP pool was " + jsonIpPool.toString());
                return false;
            }
        }

        // check host routes
        JsonNode jsonHostRoutes = jsonNode.get(HOST_ROUTES);
        if (jsonHostRoutes != null) {
            if (jsonHostRoutes.size() != network.hostRoutes().size()) {
                description.appendText("host routes size was " + jsonHostRoutes.size());
                return false;
            }

            for (KubevirtHostRoute hostRoute : network.hostRoutes()) {
                boolean routeFound = false;
                for (int routeIndex = 0; routeIndex < jsonHostRoutes.size(); routeIndex++) {
                    KubevirtHostRouteJsonMatcher routeMatcher =
                            KubevirtHostRouteJsonMatcher.matchesKubevirtHostRoute(hostRoute);
                    if (routeMatcher.matches(jsonHostRoutes.get(routeIndex))) {
                        routeFound = true;
                        break;
                    }
                }

                if (!routeFound) {
                    description.appendText("Host route not found " + hostRoute.toString());
                    return false;
                }
            }
        }

        return true;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText(network.toString());
    }

    /**
     * Factory to allocate an kubevirt network matcher.
     *
     * @param network kubevirt network object we are looking for
     * @return matcher
     */
    public static KubevirtNetworkJsonMatcher
                    matchesKubevirtNetwork(KubevirtNetwork network) {
        return new KubevirtNetworkJsonMatcher(network);
    }
}
