/*
 * Copyright 2017-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.restconf.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.io.IOUtils;
import org.onlab.osgi.DefaultServiceDirectory;
import java.io.IOException;
import java.io.InputStream;

import org.onosproject.restconf.utils.exceptions.RestconfUtilsException;
import org.onosproject.restconf.api.RestconfException;
import org.onosproject.yang.runtime.CompositeStream;
import org.onosproject.yang.runtime.CompositeData;
import org.onosproject.yang.runtime.YangRuntimeService;
import org.onosproject.yang.runtime.DefaultCompositeStream;
import org.onosproject.yang.runtime.DefaultCompositeData;
import org.onosproject.yang.runtime.DefaultResourceData;
import org.onosproject.yang.runtime.RuntimeContext;
import org.onosproject.yang.model.ResourceData;
import org.onosproject.yang.model.ResourceId;
import org.onosproject.yang.model.DataNode;

import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;

/**
 * Utilities used by the RESTCONF app.
 */
public final class RestconfUtils {
    /**
     * No instantiation.
     */
    private RestconfUtils() {
    }

    /**
     * Data format required by YangRuntime Service.
     */
    private static final String JSON_FORMAT = "json";

    private static final YangRuntimeService YANG_RUNTIME =
            DefaultServiceDirectory.getService(YangRuntimeService.class);

    /**
     * Converts an input stream to JSON objectNode.
     *
     * @param  inputStream the InputStream from Resource Data
     * @return JSON representation of the data resource
     */
    public static ObjectNode convertInputStreamToObjectNode(InputStream inputStream) {
        ObjectNode rootNode;
        ObjectMapper mapper = new ObjectMapper();
        try {
            rootNode = (ObjectNode) mapper.readTree(inputStream);
        } catch (IOException e) {
            throw new RestconfUtilsException("ERROR: InputStream failed to parse");
        }
        return rootNode;
    }

    /**
     * Convert ObjectNode to InputStream.
     *
     * @param  rootNode JSON representation of the data resource
     * @return the InputStream from Resource Data
     */
    public static InputStream convertObjectNodeToInputStream(ObjectNode rootNode) {
        String json = rootNode.asText();
        InputStream inputStream;
        try {
            inputStream = IOUtils.toInputStream(json);
        } catch (Exception e) {
            throw new RestconfUtilsException("ERROR: Json Node failed to parse");
        }
        return inputStream;
    }

    /**
     * Convert URI to ResourceId.
     *
     * @param  uri URI of the data resource
     * @return resource identifier
     */
    public static ResourceId convertUriToRid(String uri) {
        ResourceData resourceData = convertJsonToDataNode(uri, null);
        return resourceData.resourceId();
    }

    /**
     * Convert URI and ObjectNode to ResourceData.
     *
     * @param  uri URI of the data resource
     * @param  rootNode JSON representation of the data resource
     * @return represents type of node in data store
     */
    public static ResourceData convertJsonToDataNode(String uri,
                                                    ObjectNode rootNode) {
        RuntimeContext.Builder runtimeContextBuilder = null;
        runtimeContextBuilder.setDataFormat(JSON_FORMAT);
        RuntimeContext context = runtimeContextBuilder.build();
        InputStream jsonData = null;
        if (rootNode != null) {
            jsonData = convertObjectNodeToInputStream(rootNode);
        }
        CompositeStream compositeStream = new DefaultCompositeStream(uri, jsonData);
        // CompositeStream --- YangRuntimeService ---> CompositeData.
        CompositeData compositeData = YANG_RUNTIME.decode(compositeStream, context);
        ResourceData resourceData = compositeData.resourceData();
        return resourceData;
    }

    /**
     * Convert Resource Id and Data Node to Json ObjectNode.
     *
     * @param  rid resource identifier
     * @param  dataNode represents type of node in data store
     * @return JSON representation of the data resource
     */
    public static ObjectNode convertDataNodeToJson(ResourceId rid, DataNode dataNode) {
        RuntimeContext.Builder runtimeContextBuilder = null;
        runtimeContextBuilder.setDataFormat(JSON_FORMAT);
        RuntimeContext context = runtimeContextBuilder.build();
        DefaultResourceData.Builder resourceDataBuilder = DefaultResourceData.builder();
        resourceDataBuilder.addDataNode(dataNode);
        resourceDataBuilder.resourceId(rid);
        ResourceData resourceData = resourceDataBuilder.build();
        DefaultCompositeData.Builder compositeDataBuilder = DefaultCompositeData.builder();
        compositeDataBuilder.resourceData(resourceData);
        CompositeData compositeData = compositeDataBuilder.build();
        // CompositeData --- YangRuntimeService ---> CompositeStream.
        CompositeStream compositeStream = YANG_RUNTIME.encode(compositeData, context);
        InputStream inputStream = compositeStream.resourceData();
        ObjectNode rootNode = convertInputStreamToObjectNode(inputStream);
        if (rootNode == null) {
            throw new RestconfException("ERROR: InputStream can not be convert to ObjectNode",
                                        INTERNAL_SERVER_ERROR);
        }
        return rootNode;
    }
}
