/*
 * 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 com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.util.HexString;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.core.GroupId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.group.DefaultGroup;
import org.onosproject.net.group.DefaultGroupDescription;
import org.onosproject.net.group.DefaultGroupKey;
import org.onosproject.net.group.Group;
import org.onosproject.net.group.GroupBucket;
import org.onosproject.net.group.GroupBuckets;
import org.onosproject.net.group.GroupDescription;
import org.onosproject.net.group.GroupKey;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Group JSON codec.
 */
public final class GroupCodec extends JsonCodec<Group> {
    private final Logger log = getLogger(getClass());

    // JSON field names
    private static final String ID = "id";
    private static final String STATE = "state";
    private static final String LIFE = "life";
    private static final String PACKETS = "packets";
    private static final String BYTES = "bytes";
    private static final String REFERENCE_COUNT = "referenceCount";
    private static final String TYPE = "type";
    private static final String GROUP_ID = "groupId";
    private static final String DEVICE_ID = "deviceId";
    private static final String APP_ID = "appId";
    private static final String APP_COOKIE = "appCookie";
    private static final String GIVEN_GROUP_ID = "givenGroupId";
    private static final String BUCKETS = "buckets";
    private static final String MISSING_MEMBER_MESSAGE =
            " member is required in Group";
    public static final String REST_APP_ID = "org.onosproject.rest";

    @Override
    public ObjectNode encode(Group group, CodecContext context) {
        checkNotNull(group, "Group cannot be null");
        ObjectNode result = context.mapper().createObjectNode()
                .put(ID, group.id().toString())
                .put(STATE, group.state().toString())
                .put(LIFE, group.life())
                .put(PACKETS, group.packets())
                .put(BYTES, group.bytes())
                .put(REFERENCE_COUNT, group.referenceCount())
                .put(TYPE, group.type().toString())
                .put(DEVICE_ID, group.deviceId().toString());

        if (group.appId() != null) {
            result.put(APP_ID, group.appId().toString());
        }

        if (group.appCookie() != null) {
            result.put(APP_COOKIE, group.appCookie().toString());
        }

        if (group.givenGroupId() != null) {
            result.put(GIVEN_GROUP_ID, group.givenGroupId());
        }

        ArrayNode buckets = context.mapper().createArrayNode();
        group.buckets().buckets().forEach(bucket -> {
            ObjectNode bucketJson = context.codec(GroupBucket.class).encode(bucket, context);
            buckets.add(bucketJson);
        });
        result.set(BUCKETS, buckets);
        return result;
    }

    @Override
    public Group decode(ObjectNode json, CodecContext context) {
        if (json == null || !json.isObject()) {
            return null;
        }

        final JsonCodec<GroupBucket> groupBucketCodec = context.codec(GroupBucket.class);
        CoreService coreService = context.getService(CoreService.class);

        // parse group id
        int groupIdInt = nullIsIllegal(json.get(GROUP_ID),
                GROUP_ID + MISSING_MEMBER_MESSAGE).asInt();
        GroupId groupId = new DefaultGroupId(groupIdInt);

        // parse group key (appCookie)
        String groupKeyStr = nullIsIllegal(json.get(APP_COOKIE),
                APP_COOKIE + MISSING_MEMBER_MESSAGE).asText();
        if (!groupKeyStr.startsWith("0x")) {
            throw new IllegalArgumentException("APP_COOKIE must be a hex string starts with 0x");
        }
        GroupKey groupKey = new DefaultGroupKey(HexString.fromHexString(
                groupKeyStr.split("0x")[1], ""));

        // parse device id
        DeviceId deviceId = DeviceId.deviceId(nullIsIllegal(json.get(DEVICE_ID),
                DEVICE_ID + MISSING_MEMBER_MESSAGE).asText());

        // application id
        ApplicationId appId = coreService.registerApplication(REST_APP_ID);

        // parse group type
        String type = nullIsIllegal(json.get(TYPE),
                TYPE + MISSING_MEMBER_MESSAGE).asText();
        GroupDescription.Type groupType = null;

        switch (type) {
            case "SELECT":
                groupType = Group.Type.SELECT;
                break;
            case "INDIRECT":
                groupType = Group.Type.INDIRECT;
                break;
            case "ALL":
                groupType = Group.Type.ALL;
                break;
            case "FAILOVER":
                groupType = Group.Type.FAILOVER;
                break;
            default:
                nullIsIllegal(groupType, "The requested group type " + type + " is not valid");
        }

        // parse group buckets

        GroupBuckets buckets = null;
        List<GroupBucket> groupBucketList = new ArrayList<>();
        JsonNode bucketsJson = json.get(BUCKETS);
        checkNotNull(bucketsJson);
        if (bucketsJson != null) {
            IntStream.range(0, bucketsJson.size())
                    .forEach(i -> {
                        ObjectNode bucketJson = get(bucketsJson, i);
                        bucketJson.put("type", type);
                        groupBucketList.add(groupBucketCodec.decode(bucketJson, context));
                    });
            buckets = new GroupBuckets(groupBucketList);
        }

        GroupDescription groupDescription = new DefaultGroupDescription(deviceId,
                groupType, buckets, groupKey, groupIdInt, appId);

        return new DefaultGroup(groupId, groupDescription);
    }
}
