/*
 * Copyright 2016-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.yms.ych;

import org.onosproject.yms.ydt.YmsOperationType;

import java.util.List;
import java.util.Map;

/**
 * Abstraction of an entity which provides interfaces to YANG codec handler.
 * <p>
 * In SBI, the provider or driver uses YANG management system as a CODEC
 * utility. Providers/drivers register the device schema with YANG management
 * system. YANG utils is used to generate the java files corresponding to the
 * device schema. Provider or driver use these classes to seamlessly manage
 * the device as java objects. While sending the request to device, drivers
 * use the utility to translate the objects to protocol specific data
 * representation and then send to the device. Protocol or driver use the
 * same instance of the codec utility across multiple translation request.
 * Protocol or driver should not use the same instance of utility concurrently.
 */
public interface YangCodecHandler {
    /**
     * Provider / driver needs to register the device schema with code handler.
     * Then the provider / driver can use the codec handler to perform the
     * codec operation. When the codec operation is  being performed, the
     * codec utility finds the mapping registered device model and perform the
     * translation against the device schema.
     *
     * @param yangModule YANG utils generated class corresponding to SBI
     *                   device schema module
     */
    void addDeviceSchema(Class<?> yangModule);


    /**
     * When the drivers / providers need to encode a protocol operation
     * requests, which is in a single block, this encode API is used.
     * A single protocol operation can span across multiple application, then
     * the driver / provider need to provide the list of application(s) module
     * object. Each module object contains the request information
     * corresponding to that application.
     * <p>
     * The protocols can have a logical root node which acts as a container
     * of applications module node. For example in NETCONF, it could be
     * data/filter/config, etc. Protocols needs to pass this parameter in the
     * encode request, so that it is part of the encoded protocol packet.
     * There is no validation done on the value of this parameter. It is up to
     * the protocol to use it. It is a mandatory parameter and protocols must
     * pass this parameter. In protocols like NETCONF, these logical root
     * node may be in a specific name space, in such cases, it needs to be
     * passed to encode it as part of the request. There could be additional
     * tags that can be attached to the root node, for example in NETCONF,
     * the tag type="subtree" can be specified. In such scenarios the
     * required tags should be sent as a parameter.
     * <p>
     * The provider / driver would require to operate on multiple schema
     * nodes in a single request, for example it may be require to configure
     * a tunnel and associate a QOS to this tunnel, in this scenario, it
     * needs to have the tunnel related information in the tunnel module's
     * Java object and and QOS related  information in QOS modules Java
     * object. So in a single request, it can send the list of Java objects
     * corresponding to the modules which need to participate in the operation.
     * If the request to be generated needs to be a wild card for no
     * application(s), then this parameter needs to be null. For example a
     * "empty filter" request in NETCONF get request.
     * <p>
     * If the request to be generated needs to be a wild card for  all
     * application(s), then the driver / provider should not invoke this API,
     * as there is no encoding of application related information for the
     * operation, it is only limited to the protocol operation. For example a
     * "no filter" request in NETCONF get request.
     *
     * @param rootName              name of logical root node as required by
     *                              the protocol
     * @param rootNamespace         namespace of logical root node as
     *                              required by the protocol encoding. It is
     *                              an optional parameter.
     * @param tagAttributeLinkedMap Specifies the list of attributes that
     *                              needs to be tagged with the logical root
     *                              node. It is an optional parameter
     *                              if not required for the protocol.
     * @param yangModuleList        list of YANG module's object(s)
     *                              participating in the operation.
     * @param dataFormat            data format to which encoding to be done.
     * @param protocolOperation     protocol operation being performed
     * @return string containing the requested applications object
     * information encoded in protocol format.
     */
    String encodeOperation(String rootName, String rootNamespace,
                           Map<String, String> tagAttributeLinkedMap,
                           List<Object> yangModuleList,
                           YangProtocolEncodingFormat dataFormat,
                           YmsOperationType protocolOperation);

    /**
     * When the drivers / providers need to encode protocol composite
     * operation requests, which is split in a composite blocks, this encode
     * composite operation API is used. The application module object
     * containing the request information has both the resource identifier
     * part and the resource information part.
     * <p>
     * The protocols can have a logical root node which acts as a container
     * of applications module node.  For example in RESTCONF, it could be
     * RootResource/data, etc. There is no validation done on the value
     * of this parameter. It is upto the protocol to use it. It is a
     * mandatory parameter and protocols must pass this parameter.
     * <p>
     * The resource to be operated upon in the device is identified in a
     * module's schema object. This modules object should contain the
     * information about the resource on which the operation needs to be
     * performed. The resource is identified by initial chain of objects for
     * which operation type is none. Once the resource is reached using none
     * operations, the actual information about the operation on the device
     * is encoded.
     *
     * @param rootName          name of logical root node as required by the
     *                          protocol
     * @param rootNamespace     namespace of logical root node as required by
     *                          the
     *                          protocol encoding. It is optional, and there
     *                          is no
     *                          namespace set to the logical root node
     * @param appModuleObject   object containing the information about the
     *                          resource on which the operation is being
     *                          performed
     * @param dataFormat        data format to which request needs to
     *                          be encoded
     * @param protocolOperation protocol operation being performed
     * @return the composite protocol operation request.
     */
    YangCompositeEncoding encodeCompositeOperation(String rootName,
                                                   String rootNamespace,
                                                   Object appModuleObject,
                                                   YangProtocolEncodingFormat
                                                           dataFormat,
                                                   YmsOperationType
                                                           protocolOperation);

    /**
     * When the driver or provider receive the data from the SBI protocol, It
     * will be in the protocol specific data representation. Drivers /
     * provider need to interact with the device using native JAVA objects.
     * Drivers use this decode method to translate the received
     * protocol specific simple data to YANG modeled Java objects.
     * If the response received is not in line with the schema, for example,
     * there is some error info, etc, then the decode operation will throw an
     * exception and decode operation will fail.
     *
     * @param protocolData      input string containing the resource information
     *                          in protocol format
     * @param dataFormat        data format from which decoding has to be done
     * @param protocolOperation protocol operation being performed
     * @return list of applications module/notification objects corresponding
     * to the protocol data input
     */
    List<Object> decode(String protocolData,
                        YangProtocolEncodingFormat dataFormat,
                        YmsOperationType protocolOperation);

    /**
     * When the driver or provider receive the composite data from the SBI
     * protocol, It will be in the protocol specific data representation.
     * Drivers / provider need to interact with the device
     * using native JAVA objects. Drivers use this Decode method to translate
     * the received protocol specific composite data to YANG modeled Java
     * objects.
     * <p>
     * If the response received is not in line with the schema, for example,
     * there is some error info, etc, then the decode operation will throw an
     * exception and decode operation will fail.
     *
     * @param protocolData      composite protocol data containing the resource
     *                          information
     * @param dataFormat        data format from which decoding has to be done
     * @param protocolOperation protocol operation being performed
     * @return application module/notification object corresponding to the
     * protocol data infput
     */
    Object decode(YangCompositeEncoding protocolData,
                  YangProtocolEncodingFormat dataFormat,
                  YmsOperationType protocolOperation);

    /**
     * Register the provider / driver specific overridden codec. This is can
     * be used by provider to support  any protocol specific extension or
     * vendor specific implementation. This framework can also be used
     * by providers / drivers to support any new protocol data format which
     * is not supported by default in YANG codec utility.
     *
     * @param overriddenCodec provider / driver specific overridden instance
     *                        of the codec
     * @param dataFormat      data format to which encoding to be done.
     */
    void registerOverriddenCodec(YangDataTreeCodec overriddenCodec,
                                 YangProtocolEncodingFormat dataFormat);
}
