/*
 * Copyright 2015 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);
    }
}
