/*
 * 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.codec.impl;

import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.onosproject.net.group.Group;
import org.onosproject.net.group.GroupBucket;

import com.fasterxml.jackson.databind.JsonNode;

/**
 * Hamcrest matcher for groups.
 */

public final class GroupJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {

    private final Group group;

    private GroupJsonMatcher(Group group) {
        this.group = group;
    }

    @Override
    public boolean matchesSafely(JsonNode jsonGroup, Description description) {
        // check id
        String jsonGroupId = jsonGroup.get("id").asText();
        String groupId = group.id().toString();
        if (!jsonGroupId.equals(groupId)) {
            description.appendText("group id was " + jsonGroupId);
            return false;
        }

        // check state
        String jsonState = jsonGroup.get("state").asText();
        String state = group.state().toString();
        if (!jsonState.equals(state)) {
            description.appendText("state was " + jsonState);
            return false;
        }

        // check life
        long jsonLife = jsonGroup.get("life").asLong();
        long life = group.life();
        if (life != jsonLife) {
            description.appendText("life was " + jsonLife);
            return false;
        }

        // check bytes
        long jsonBytes = jsonGroup.get("bytes").asLong();
        long bytes = group.bytes();
        if (bytes != jsonBytes) {
            description.appendText("bytes was " + jsonBytes);
            return false;
        }

        // check packets
        long jsonPackets = jsonGroup.get("packets").asLong();
        long packets = group.packets();
        if (packets != jsonPackets) {
            description.appendText("packets was " + jsonPackets);
            return false;
        }

        // check size of bucket array
        JsonNode jsonBuckets = jsonGroup.get("buckets");
        if (jsonBuckets.size() != group.buckets().buckets().size()) {
            description.appendText("buckets size was " + jsonBuckets.size());
            return false;
        }

        // Check buckets
        for (GroupBucket bucket : group.buckets().buckets()) {
            boolean bucketFound = false;
            for (int bucketIndex = 0; bucketIndex < jsonBuckets.size(); bucketIndex++) {
                GroupBucketJsonMatcher bucketMatcher =
                        GroupBucketJsonMatcher.matchesGroupBucket(bucket);
                if (bucketMatcher.matches(jsonBuckets.get(bucketIndex))) {
                    bucketFound = true;
                    break;
                }
            }
            if (!bucketFound) {
                description.appendText("bucket not found " + bucket.toString());
                return false;
            }
        }

        return true;
    }

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

    /**
     * Factory to allocate a group matcher.
     *
     * @param group group object we are looking for
     * @return matcher
     */
    public static GroupJsonMatcher matchesGroup(Group group) {
        return new GroupJsonMatcher(group);
    }
}
