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

import org.onosproject.yms.app.ych.defaultcodecs.YangCodecRegistry;
import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
import org.onosproject.yms.app.ydt.YdtExtendedContext;
import org.onosproject.yms.app.yob.DefaultYobBuilder;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
import org.onosproject.yms.app.ytb.DefaultYangTreeBuilder;
import org.onosproject.yms.app.ytb.YtbException;
import org.onosproject.yms.ych.YangCodecHandler;
import org.onosproject.yms.ych.YangCompositeEncoding;
import org.onosproject.yms.ych.YangDataTreeCodec;
import org.onosproject.yms.ych.YangProtocolEncodingFormat;
import org.onosproject.yms.ydt.YdtBuilder;
import org.onosproject.yms.ydt.YdtContext;
import org.onosproject.yms.ydt.YmsOperationType;
import org.onosproject.yms.ysr.YangModuleLibrary;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Represents implementation of YANG SBI broker interfaces.
 * YCH acts as a broker between YMS and driver/provider.
 */
public class DefaultYangCodecHandler implements YangCodecHandler {

    private static final String E_MODULE_LIST = "The input module or " +
            "sub-module object list cannot be null.";
    private static final String E_DATA_TREE_CODEC = "data tree codec handler" +
            " is null.";

    /**
     * Schema registry for driver.
     */
    private final YangSchemaRegistry schemaRegistry;
    private YangModuleLibrary library;

    /**
     * Default codecs.
     */
    private final Map<YangProtocolEncodingFormat, YangDataTreeCodec>
            defaultCodecs = new HashMap<>();

    /**
     * Override codec handler.
     */
    private final Map<YangProtocolEncodingFormat, YangDataTreeCodec>
            overrideCodecs = new HashMap<>();

    /**
     * Creates a new YANG codec handler.
     *
     * @param registry YANG schema registry
     */
    public DefaultYangCodecHandler(YangSchemaRegistry registry) {
        schemaRegistry = registry;

        // update the default codecs from codec registry
        Map<YangProtocolEncodingFormat, YangDataTreeCodec> recvCodec =
                YangCodecRegistry.getDefaultCodecs();
        if (!recvCodec.isEmpty()) {
            for (Map.Entry<YangProtocolEncodingFormat, YangDataTreeCodec>
                    codecEntry : recvCodec.entrySet()) {
                defaultCodecs.put(codecEntry.getKey(), codecEntry.getValue());
            }
        }
    }

    private YangDataTreeCodec getAppropriateCodec(
            YangProtocolEncodingFormat dataFormat) {
        YangDataTreeCodec codec = defaultCodecs.get(dataFormat);

        int size = overrideCodecs.size();
        // Check over ridden codec handler is exist or not.
        if (size != 0) {
            YangDataTreeCodec overrideCodec = overrideCodecs.get(dataFormat);
            if (overrideCodec != null) {
                codec = overrideCodec;
            }
        }
        return codec;
    }

    @Override
    public void addDeviceSchema(Class<?> yangModule) {
        schemaRegistry.registerApplication(null, yangModule);
        schemaRegistry.processModuleLibrary(yangModule.getName(), library);
    }

    @Override
    public String encodeOperation(String rootName,
                                  String rootNamespace,
                                  Map<String, String> tagAttrMap,
                                  List<Object> moduleList,
                                  YangProtocolEncodingFormat dataFormat,
                                  YmsOperationType opType) {

        if (moduleList == null || moduleList.isEmpty()) {
            throw new YchException(E_MODULE_LIST);
        }

        // Get the default codec handler.
        YangDataTreeCodec codec = getAppropriateCodec(dataFormat);
        if (codec == null) {
            throw new YchException(E_DATA_TREE_CODEC);
        }

        // Get yang data tree from YTB for the received objects.
        DefaultYangTreeBuilder builder = new DefaultYangTreeBuilder();
        YdtExtendedBuilder encodedYdt =
                builder.getYdtBuilderForYo(moduleList, rootName,
                                           rootNamespace, opType,
                                           schemaRegistry);

        encodedYdt.setRootTagAttributeMap(tagAttrMap);

        // Get the xml string form codec handler.
        return codec.encodeYdtToProtocolFormat(encodedYdt);
    }

    @Override
    public YangCompositeEncoding encodeCompositeOperation(
            String rootName,
            String rootNamespace,
            Object moduleObject,
            YangProtocolEncodingFormat dataFormat,
            YmsOperationType opType) {

        if (moduleObject == null) {
            throw new YtbException(E_MODULE_LIST);
        }

        // Get the default codec handler.
        YangDataTreeCodec codec = getAppropriateCodec(dataFormat);
        if (codec == null) {
            throw new YchException(E_DATA_TREE_CODEC);
        }

        List<Object> yangModuleList = new ArrayList<>();
        yangModuleList.add(moduleObject);

        // Get yang data tree from YTB for the received objects.
        DefaultYangTreeBuilder builder = new DefaultYangTreeBuilder();
        YdtExtendedBuilder extBuilder =
                builder.getYdtBuilderForYo(yangModuleList,
                                           rootName,
                                           rootNamespace,
                                           opType,
                                           schemaRegistry);

        // Get the composite response from codec handler.
        return codec.encodeYdtToCompositeProtocolFormat(extBuilder);
    }

    @Override
    public List<Object> decode(String inputString,
                               YangProtocolEncodingFormat dataFormat,
                               YmsOperationType opType) {

        YdtBuilder ydtBuilder;
        YangDataTreeCodec codec = getAppropriateCodec(dataFormat);
        if (codec == null) {
            throw new YchException(E_DATA_TREE_CODEC);
        }

        try {
            // Get the YANG data tree
            ydtBuilder = codec.decodeProtocolDataToYdt(inputString,
                                                       schemaRegistry,
                                                       opType);
        } catch (Exception e) {
            throw new YchException(e.getLocalizedMessage());
        }

        if (ydtBuilder != null) {
            return getObjectList(ydtBuilder.getRootNode());
        }

        return null;
    }

    @Override
    public Object decode(YangCompositeEncoding protoData,
                         YangProtocolEncodingFormat dataFormat,
                         YmsOperationType opType) {

        YangDataTreeCodec codec = getAppropriateCodec(dataFormat);
        if (codec == null) {
            throw new YchException(E_DATA_TREE_CODEC);
        }

        YdtBuilder ydtBuilder =
                codec.decodeCompositeProtocolDataToYdt(protoData,
                                                       schemaRegistry,
                                                       opType);

        // Get the module object by using YANG data tree
        if (ydtBuilder != null) {
            return getObjectList(ydtBuilder.getRootNode());
        }

        return null;
    }

    @Override
    public void registerOverriddenCodec(YangDataTreeCodec overrideCodec,
                                        YangProtocolEncodingFormat dataFormat) {
        overrideCodecs.put(dataFormat, overrideCodec);
    }

    /**
     * Returns the list of objects from YDT data tree.
     *
     * @param rootNode YDT root node
     * @return returns list of objects
     */
    private List<Object> getObjectList(YdtContext rootNode) {

        if (rootNode == null) {
            // TODO
            return null;
        }

        if (rootNode.getFirstChild() == null) {
            // TODO
            return null;
        }

        YdtContext curNode = rootNode.getFirstChild();
        DefaultYobBuilder builder = new DefaultYobBuilder();
        Object object = builder.getYangObject((YdtExtendedContext) curNode,
                                              schemaRegistry);
        List<Object> objectList = new ArrayList<>();
        objectList.add(object);

        // Check next module is exit or not. If exist get the object for that.
        while (curNode.getNextSibling() != null) {
            curNode = curNode.getNextSibling();
            object = builder.getYangObject((YdtExtendedContext) curNode,
                                           schemaRegistry);
            objectList.add(object);
        }

        return objectList;
    }

    /**
     * Returns module library for YSR.
     *
     * @return module library for YSR
     */
    public YangModuleLibrary getLibrary() {
        return library;
    }

    /**
     * Sets module library for YSR.
     *
     * @param library module library for YSR
     */
    public void setLibrary(YangModuleLibrary library) {
        this.library = library;
    }
}
