/*
 * Copyright 2019-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.k8snode.codec;

import com.fasterxml.jackson.databind.JsonNode;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.onlab.packet.IpAddress;
import org.onosproject.k8snode.api.K8sNode;

/**
 * Hamcrest matcher for kubernetes node.
 */
public final class K8sNodeJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {

    private final K8sNode node;

    private static final String CLUSTER_NAME = "clusterName";
    private static final String HOSTNAME = "hostname";
    private static final String TYPE = "type";
    private static final String SEGMENT_ID = "segmentId";
    private static final String MANAGEMENT_IP = "managementIp";
    private static final String DATA_IP = "dataIp";
    private static final String INTEGRATION_BRIDGE = "integrationBridge";
    private static final String STATE = "state";
    private static final String EXTERNAL_INTF = "externalInterface";
    private static final String EXTERNAL_BRIDGE_IP = "externalBridgeIp";
    private static final String EXTERNAL_GATEWAY_IP = "externalGatewayIp";

    private K8sNodeJsonMatcher(K8sNode node) {
        this.node = node;
    }

    @Override
    protected boolean matchesSafely(JsonNode jsonNode, Description description) {

        // check cluster name
        String jsonClusterName = jsonNode.get(CLUSTER_NAME).asText();
        String clusterName = node.clusterName();
        if (!jsonClusterName.equals(clusterName)) {
            description.appendText("cluster name was " + jsonClusterName);
            return false;
        }

        // check hostname
        String jsonHostname = jsonNode.get(HOSTNAME).asText();
        String hostname = node.hostname();
        if (!jsonHostname.equals(hostname)) {
            description.appendText("hostname was " + jsonHostname);
            return false;
        }

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

        // check segment ID
        JsonNode jsonSegmentId = jsonNode.get(SEGMENT_ID);
        if (jsonSegmentId != null) {
            int segmentId = jsonSegmentId.asInt();
            if (segmentId != node.segmentId()) {
                description.appendText("segment ID was " + segmentId);
                return false;
            }
        }

        // check management IP
        String jsonMgmtIp = jsonNode.get(MANAGEMENT_IP).asText();
        String mgmtIp = node.managementIp().toString();
        if (!jsonMgmtIp.equals(mgmtIp)) {
            description.appendText("management IP was " + jsonMgmtIp);
            return false;
        }

        // check integration bridge
        JsonNode jsonIntgBridge = jsonNode.get(INTEGRATION_BRIDGE);
        if (jsonIntgBridge != null) {
            String intgBridge = node.intgBridge().toString();
            if (!jsonIntgBridge.asText().equals(intgBridge)) {
                description.appendText("integration bridge was " + jsonIntgBridge);
                return false;
            }
        }

        // check state
        String jsonState = jsonNode.get(STATE).asText();
        String state = node.state().name();
        if (!jsonState.equals(state)) {
            description.appendText("state was " + jsonState);
            return false;
        }

        // check data IP
        JsonNode jsonDataIp = jsonNode.get(DATA_IP);
        if (jsonDataIp != null) {
            String dataIp = node.dataIp().toString();
            if (!jsonDataIp.asText().equals(dataIp)) {
                description.appendText("Data IP was " + jsonDataIp.asText());
                return false;
            }
        }

        // check external interface
        JsonNode jsonExtIntf = jsonNode.get(EXTERNAL_INTF);
        if (jsonExtIntf != null) {
            String extIntf = node.extIntf();
            if (!jsonExtIntf.asText().equals(extIntf)) {
                description.appendText("External interface was " + jsonExtIntf.asText());
                return false;
            }
        }

        // check external bridge IP
        JsonNode jsonExtBridgeIp = jsonNode.get(EXTERNAL_BRIDGE_IP);
        if (jsonExtBridgeIp != null) {
            IpAddress extBridgeIp = node.extBridgeIp();
            if (!jsonExtBridgeIp.asText().equals(extBridgeIp.toString())) {
                description.appendText("External bridge IP was " + jsonExtBridgeIp.asText());
                return false;
            }
        }

        // check external gateway IP
        JsonNode jsonExtGatewayIp = jsonNode.get(EXTERNAL_GATEWAY_IP);
        if (jsonExtGatewayIp != null) {
            IpAddress extGatewayIp = node.extGatewayIp();
            if (!jsonExtGatewayIp.asText().equals(extGatewayIp.toString())) {
                description.appendText("External gateway IP was " + jsonExtGatewayIp.asText());
                return false;
            }
        }

        return true;
    }

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

    /**
     * Factory to allocate an kubernetes node matcher.
     *
     * @param node kubernetes node object we are looking for
     * @return matcher
     */
    public static K8sNodeJsonMatcher matchesK8sNode(K8sNode node) {
        return new K8sNodeJsonMatcher(node);
    }
}
