/*
 * Copyright 2017-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.netconf.client.impl;

import com.google.common.annotations.Beta;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.cluster.NodeId;
import org.onosproject.net.DeviceId;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfDevice;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.onosproject.netconf.client.NetconfTranslator;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.InnerNode;
import org.onosproject.yang.model.KeyLeaf;
import org.onosproject.yang.model.LeafListKey;
import org.onosproject.yang.model.LeafNode;
import org.onosproject.yang.model.ListKey;
import org.onosproject.yang.model.NodeKey;
import org.onosproject.yang.model.ResourceData;
import org.onosproject.yang.model.ResourceId;
import org.onosproject.yang.model.SchemaContext;
import org.onosproject.yang.model.SchemaContextProvider;
import org.onosproject.yang.model.SchemaId;
import org.onosproject.yang.runtime.CompositeStream;
import org.onosproject.yang.runtime.DefaultAnnotatedNodeInfo;
import org.onosproject.yang.runtime.DefaultAnnotation;
import org.onosproject.yang.runtime.DefaultCompositeData;
import org.onosproject.yang.runtime.DefaultCompositeStream;
import org.onosproject.yang.model.DefaultResourceData;
import org.onosproject.yang.runtime.DefaultRuntimeContext;
import org.onosproject.yang.runtime.DefaultYangSerializerContext;
import org.onosproject.yang.runtime.YangRuntimeService;
import org.onosproject.yang.runtime.YangSerializerContext;
import org.onosproject.yang.runtime.SerializerHelper;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.netconf.DatastoreId.RUNNING;
import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE;
import static org.onosproject.yang.runtime.SerializerHelper.addDataNode;

/*FIXME these imports are not visible using OSGI*/

/*FIXME these imports are not visible using OSGI*/

/*TODO once the API's are finalized this comment will be made more specified.*/

/**
 * Translator which accepts data types defined for the DynamicConfigService and
 * makes the appropriate calls to NETCONF devices before encoding and returning
 * responses in formats suitable for the DynamicConfigService.
 * <p>
 * NOTE: This entity does not ensure you are the master of a device you attempt
 * to contact. If you are not the master an error will be thrown because there
 * will be no session available.
 */
@Beta
@Service
@Component(immediate = true)
public class NetconfTranslatorImpl implements NetconfTranslator {

    private static final Logger log = LoggerFactory
            .getLogger(NetconfTranslator.class);

    private NodeId localNodeId;

    private static final String GET_CONFIG_MESSAGE_REGEX =
            "<data>\n?\\s*(.*?)\n?\\s*</data>";
    private static final int GET_CONFIG_CORE_MESSAGE_GROUP = 1;
    private static final Pattern GET_CONFIG_CORE_MESSAGE_PATTERN =
            Pattern.compile(GET_CONFIG_MESSAGE_REGEX, Pattern.DOTALL);
    private static final String GET_CORE_MESSAGE_REGEX = "<data>\n?\\s*(.*?)\n?\\s*</data>";
    private static final int GET_CORE_MESSAGE_GROUP = 1;
    private static final Pattern GET_CORE_MESSAGE_PATTERN =
            Pattern.compile(GET_CORE_MESSAGE_REGEX, Pattern.DOTALL);

    private static final String NETCONF_1_0_BASE_NAMESPACE =
            "urn:ietf:params:xml:ns:netconf:base:1.0";

    private static final String GET_URI = "urn:ietf:params:xml:ns:yang:" +
            "yrt-ietf-network:networks/network/node";
    private static final String XML_ENCODING_SPECIFIER = "xml";
    private static final String OP_SPECIFIER = "xc:operation";
    private static final String REPLACE_OP_SPECIFIER = "replace";
    private static final String DELETE_OP_SPECIFIER = "delete";
    private static final String XMLNS_XC_SPECIFIER = "xmlns:xc";
    private static final String XMLNS_SPECIFIER = "xmlns";

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetconfController netconfController;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected YangRuntimeService yangRuntimeService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected SchemaContextProvider schemaContextProvider;

    @Activate
    public void activate(ComponentContext context) {
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        log.info("Stopped");
    }

    @Override
    public ResourceData getDeviceConfig(DeviceId deviceId) throws IOException {
        NetconfSession session = getNetconfSession(deviceId);
        /*FIXME "running" will be replaced with an enum once netconf supports multiple datastores.*/
        String reply = session.getConfig(RUNNING);
        Matcher protocolStripper = GET_CONFIG_CORE_MESSAGE_PATTERN.matcher(reply);
        reply = protocolStripper.group(GET_CONFIG_CORE_MESSAGE_GROUP);
        return yangRuntimeService.decode(
                new DefaultCompositeStream(
                        null,
                        /*FIXME is UTF_8 the appropriate encoding? */
                        new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))),
                new DefaultRuntimeContext.Builder()
                        .setDataFormat(XML_ENCODING_SPECIFIER)
                        .addAnnotation(
                                new DefaultAnnotation(XMLNS_SPECIFIER,
                                                      NETCONF_1_0_BASE_NAMESPACE))
                        .build()).resourceData();
    }

    @Override
    public boolean editDeviceConfig(DeviceId deviceId, ResourceData resourceData,
                                    NetconfTranslator.OperationType operationType) throws IOException {
        NetconfSession session = getNetconfSession(deviceId);
        SchemaContext context = schemaContextProvider
                .getSchemaContext(ResourceId.builder().addBranchPointSchema("/", null).build());
        ResourceData modifiedPathResourceData = getResourceData(resourceData.resourceId(),
                                                                resourceData.dataNodes(),
                                                                new DefaultYangSerializerContext(context, null));
        DefaultCompositeData.Builder compositeDataBuilder = DefaultCompositeData
                .builder()
                .resourceData(modifiedPathResourceData);
        for (DataNode node : resourceData.dataNodes()) {
            ResourceId resourceId = resourceData.resourceId();
            if (operationType != OperationType.DELETE) {
                resourceId = getAnnotatedNodeResourceId(
                        resourceData.resourceId(), node);
            }
            if (resourceId != null) {
                DefaultAnnotatedNodeInfo.Builder annotatedNodeInfo =
                        DefaultAnnotatedNodeInfo.builder();
                annotatedNodeInfo.resourceId(resourceId);
                annotatedNodeInfo.addAnnotation(
                        new DefaultAnnotation(
                                OP_SPECIFIER, operationType == OperationType.DELETE ?
                                DELETE_OP_SPECIFIER : REPLACE_OP_SPECIFIER));
                compositeDataBuilder.addAnnotatedNodeInfo(annotatedNodeInfo.build());
            }
        }
        CompositeStream config = yangRuntimeService.encode(
                compositeDataBuilder.build(),
                new DefaultRuntimeContext.Builder()
                        .setDataFormat(XML_ENCODING_SPECIFIER)
                        .addAnnotation(new DefaultAnnotation(
                                XMLNS_XC_SPECIFIER, NETCONF_1_0_BASE_NAMESPACE))
                        .build());
        /* FIXME need to fix to string conversion. */

        try {
            String reply = session.requestSync(Utils.editConfig(streamToString(
                    config.resourceData())));
        } catch (NetconfException e) {
            log.error("failed to send a request sync", e);
            return false;
        }
            /* NOTE: a failure to edit is reflected as a NetconfException.*/
        return true;
    }

    @Override
    public ResourceData getDeviceState(DeviceId deviceId) throws IOException {
        NetconfSession session = getNetconfSession(deviceId);
        /*TODO the first parameter will come into use if get is required to support filters.*/
        String reply = session.get(null, null);
        Matcher protocolStripper = GET_CORE_MESSAGE_PATTERN.matcher(reply);
        reply = protocolStripper.group(GET_CORE_MESSAGE_GROUP);
        return yangRuntimeService.decode(
                new DefaultCompositeStream(
                        null,
                /*FIXME is UTF_8 the appropriate encoding? */
                        new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))),
                new DefaultRuntimeContext.Builder()
                        .setDataFormat(XML_ENCODING_SPECIFIER)
                        .addAnnotation(
                                new DefaultAnnotation(
                                        XMLNS_SPECIFIER,
                                        NETCONF_1_0_BASE_NAMESPACE))
                        .build()).resourceData();
        /* NOTE: a failure to get is reflected as a NetconfException.*/
    }

    /**
     * Returns a session for the specified deviceId if this node is its master,
     * returns null otherwise.
     *
     * @param deviceId the id of node for which we wish to retrieve a session
     * @return a NetconfSession with the specified node or null
     */
    private NetconfSession getNetconfSession(DeviceId deviceId) {
        NetconfDevice device = netconfController.getNetconfDevice(deviceId);
        checkNotNull(device, "The specified deviceId could not be found by the NETCONF controller.");
        NetconfSession session = device.getSession();
        checkNotNull(session, "A session could not be retrieved for the specified deviceId.");
        return session;
    }

    /**
     * Accepts a stream and converts it to a string.
     *
     * @param stream the stream to be converted
     * @return a string with the same sequence of characters as the stream
     * @throws IOException if reading from the stream fails
     */
    private String streamToString(InputStream stream) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
        StringBuilder builder = new StringBuilder();

        String nextLine = reader.readLine();
        while (nextLine != null) {
            builder.append(nextLine);
            nextLine = reader.readLine();
        }
        return builder.toString();
    }

    /**
     * Returns resource data having resource id as "/" and data node tree
     * starting from "/" by creating data nodes for given resource id(parent
     * node for given list of nodes) and list of child nodes.
     * <p>
     * This api will be used in encode flow only.
     *
     * @param rid   resource identifier till parent node
     * @param nodes list of data nodes
     * @param cont  yang serializer context
     * @return resource data.
     */
    public static ResourceData getResourceData(
            ResourceId rid, List<DataNode> nodes, YangSerializerContext cont) {
        if (rid == null) {
            ResourceData.Builder resData = DefaultResourceData.builder();
            for (DataNode node : nodes) {
                resData.addDataNode(node);
            }
            return resData.build();
        }
        List<NodeKey> keys = rid.nodeKeys();
        Iterator<NodeKey> it = keys.iterator();
        DataNode.Builder dbr = SerializerHelper.initializeDataNode(cont);

        // checking the resource id weather it is getting started from / or not

        while (it.hasNext()) {
            NodeKey nodekey = it.next();
            SchemaId sid = nodekey.schemaId();
            dbr = addDataNode(dbr, sid.name(), sid.namespace(),
                              null, null);
            if (nodekey instanceof ListKey) {
                for (KeyLeaf keyLeaf : ((ListKey) nodekey).keyLeafs()) {
                    String val;
                    if (keyLeaf.leafValue() == null) {
                        val = null;
                    } else {
                        val = keyLeaf.leafValAsString();
                    }
                    dbr = addDataNode(dbr, keyLeaf.leafSchema().name(),
                                      sid.namespace(), val,
                                      SINGLE_INSTANCE_LEAF_VALUE_NODE);
                }
            }
        }

        if (dbr instanceof LeafNode.Builder &&
                (nodes != null && !nodes.isEmpty())) {
            //exception "leaf/leaf-list can not have child node"
        }

        if (nodes != null && !nodes.isEmpty()) {
            // adding the parent node for given list of nodes
            for (DataNode node : nodes) {
                dbr = ((InnerNode.Builder) dbr).addNode(node);
            }
        }
/*FIXME this can be uncommented for use with versions of onos-yang-tools newer than 1.12.0-b6*/
//        while (dbr.parent() != null) {
//            dbr = SerializerHelper.exitDataNode(dbr);
//        }

        ResourceData.Builder resData = DefaultResourceData.builder();

        resData.addDataNode(dbr.build());
        resData.resourceId(null);
        return resData.build();
    }

    /**
     * Returns resource id for annotated data node by adding resource id of top
     * level data node to given resource id.
     * <p>
     * Annotation will be added to node based on the updated resource id.
     * This api will be used in encode flow only.
     *
     * @param rid  resource identifier till parent node
     * @param node data node
     * @return updated resource id.
     */
    public static ResourceId getAnnotatedNodeResourceId(ResourceId rid,
                                                        DataNode node) {

        String val;
        ResourceId.Builder rIdBldr = ResourceId.builder();
        if (rid != null) {
            try {
                rIdBldr = rid.copyBuilder();
            } catch (CloneNotSupportedException e) {
                log.debug("clone not supported", e);
            }
        } else {
            rIdBldr.addBranchPointSchema("/", null);
        }
        DataNode.Type type = node.type();
        NodeKey k = node.key();
        SchemaId sid = k.schemaId();

        switch (type) {

            case MULTI_INSTANCE_LEAF_VALUE_NODE:
                val = ((LeafListKey) k).value().toString();
                rIdBldr.addLeafListBranchPoint(sid.name(), sid.namespace(), val);
                break;

            case MULTI_INSTANCE_NODE:
                rIdBldr.addBranchPointSchema(sid.name(), sid.namespace());
// Preparing the list of key values for multiInstanceNode
                for (KeyLeaf keyLeaf : ((ListKey) node.key()).keyLeafs()) {
                    val = keyLeaf.leafValAsString();
                    rIdBldr.addKeyLeaf(keyLeaf.leafSchema().name(), sid.namespace(), val);
                }
                break;
            case SINGLE_INSTANCE_LEAF_VALUE_NODE:
            case SINGLE_INSTANCE_NODE:
                rIdBldr.addBranchPointSchema(sid.name(), sid.namespace());
                break;

            default:
                throw new IllegalArgumentException();
        }
        return rIdBldr.build();
    }
}
