/*******************************************************************************
 * Copyright (C) 2021 the Eclipse BaSyx Authors
 * 
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 ******************************************************************************/
package org.eclipse.basyx.vab.protocol.opcua.connector;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.protocol.opcua.server.BaSyxOpcUaClientRunner;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
import org.eclipse.milo.opcua.stack.core.types.structured.BrowsePath;
import org.eclipse.milo.opcua.stack.core.types.structured.CallResponse;
import org.eclipse.milo.opcua.stack.core.types.structured.RelativePath;
import org.eclipse.milo.opcua.stack.core.types.structured.RelativePathElement;
import org.eclipse.milo.opcua.stack.core.types.structured.TranslateBrowsePathsToNodeIdsResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * OPC UA connector class
 * 
 * @author kdorofeev
 *
 */
public class OpcUaConnector implements IModelProvider {
	
	private Logger logger = LoggerFactory.getLogger(OpcUaConnector.class);
	
    private String address;
    private BaSyxOpcUaClientRunner clientRunner;

    /**
     * Invoke a BaSys get operation via OPC UA
     * 
     * @param servicePath
     *            requested node path
     * @return the requested value
     * @throws Exception
     */
    @Override
    public String getModelPropertyValue(String servicePath) {
        try {
            clientRunner = new BaSyxOpcUaClientRunner(address);
            clientRunner.run();
        } catch (Exception e) {
        	logger.error("Exception in getModelPropertyValue", e);
        }
        return opcUaRead(translateBrowsePathToNodeId(servicePath)[1]);
    }

    @Override
	public void setModelPropertyValue(String servicePath, Object newValue) throws ProviderException {
        try {
            clientRunner = new BaSyxOpcUaClientRunner(address);
            clientRunner.run();
        } catch (Exception e) {
            // TODO Auto-generated catch block
        	logger.error("Exception in setModelPropertyValue", e);
        }
        opcUaWrite(translateBrowsePathToNodeId(servicePath)[1], newValue);
    }

    @Override
	public void createValue(String path, Object newEntity) throws ProviderException {

    }

    @Override
	public void deleteValue(String path) throws ProviderException {

    }

    @Override
	public void deleteValue(String path, Object obj) throws ProviderException {

    }

    @Override
	public Object invokeOperation(String servicePath, Object... parameters) throws ProviderException {
        try {
            clientRunner = new BaSyxOpcUaClientRunner(address);
            clientRunner.run();
        } catch (Exception e) {
        	logger.error("Exception in invokeOperation", e);
        }
        return opcUaMethodCall(translateBrowsePathToNodeId(servicePath), parameters);
    }

    public OpcUaConnector(String address) {
        this.address = address;
    }

    /**
     * Perform a OPC UA read request
     * 
     * @param servicePath
     * @return
     */
    private String opcUaRead(NodeId servicePath) {
        try {
            List<NodeId> nodes = new ArrayList<NodeId>();
            nodes.add(servicePath);
            CompletableFuture<List<DataValue>> result = clientRunner.read(nodes);

            return result.get().get(0).getValue().getValue().toString();

        } catch (Exception e) {
        	logger.error("Exception in opcUaRead", e);
        }
        return null;
    }

    private String opcUaMethodCall(NodeId[] methodNodes, Object[] inputParameters) {
        try {
            Variant[] inputs = new Variant[inputParameters.length];
            for (int i = 0; i < inputParameters.length; i++) {
                inputs[i] = new Variant(inputParameters[i]);
            }
            CompletableFuture<CallResponse> result = clientRunner.callMethod(methodNodes[0], methodNodes[1], inputs);
            Variant[] outputs = result.get().getResults()[0].getOutputArguments();
            String ret = "";
            for (Variant var : outputs) {
                ret += var.getValue() + " ";
            }
            return ret;
        } catch (Exception e) {
        	logger.error("Exception in opcUaMethodCall", e);
        }
        return null;
    }

    private String opcUaWrite(NodeId servicePath, Object parameter) throws ProviderException {
        try {
            List<NodeId> nodes = new ArrayList<NodeId>();
            nodes.add(servicePath);
            List<DataValue> parameters = new ArrayList<DataValue>();
            parameters.add(new DataValue(new Variant(parameter), null, null, null));
            CompletableFuture<List<StatusCode>> result = clientRunner.write(nodes, parameters);

            return result.get().get(0).toString();
        } catch (Exception e) {
        	logger.error("Exception in opcUaWrite", e);
        }
        return null;
    }

    private NodeId[] translateBrowsePathToNodeId(String path) {
        String[] nodes = path.split("/");
        List<RelativePathElement> rpe_list = new ArrayList<RelativePathElement>();
        for (String node : nodes) {
            if (node.split(":").length != 2) {
            	logger.warn("OpcUaName should be in form namespaceIdx:identifier");
            }
            int nsIdx = Integer.valueOf(node.split(":")[0]);
            String name = node.split(":")[1];
            rpe_list.add(new RelativePathElement(Identifiers.HierarchicalReferences, false, true,
                    new QualifiedName(nsIdx, name)));
        }
        RelativePathElement[] rpe_node_arr = new RelativePathElement[rpe_list.size()];
        RelativePathElement[] rpe_parent_arr = new RelativePathElement[rpe_list.size() - 1];
        rpe_node_arr = rpe_list.toArray(rpe_node_arr);

        // get list for parent (all but the last one)
        rpe_list.remove(rpe_list.size() - 1);
        rpe_parent_arr = rpe_list.toArray(rpe_parent_arr);

        BrowsePath bp_node = new BrowsePath(Identifiers.RootFolder, new RelativePath(rpe_node_arr));
        BrowsePath bp_parent = new BrowsePath(Identifiers.RootFolder, new RelativePath(rpe_parent_arr));
        List<BrowsePath> bp_node_list = new ArrayList<BrowsePath>();
        List<BrowsePath> bp_parent_list = new ArrayList<BrowsePath>();
        bp_node_list.add(bp_node);
        bp_parent_list.add(bp_parent);
        try {
            CompletableFuture<TranslateBrowsePathsToNodeIdsResponse> result_node = clientRunner.translate(bp_node_list);
            CompletableFuture<TranslateBrowsePathsToNodeIdsResponse> result_parent = clientRunner
                    .translate(bp_parent_list);
            if (result_node.get().getResults().length == 0) {
                logger.warn("TranslateBrowsePathsToNodeIdsResponse result size = 0, checkthe browse path!");
                return null;
            }
            if (result_node.get().getResults().length > 1) {
            	logger.warn("TranslateBrowsePathsToNodeIdsResponse result size > 1, the method returns only the first one!");
            }
            if (result_node.get().getResults()[0].getTargets().length > 1) {
            	logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size > 1, the method returns only the first one!");
            }
            if (result_node.get().getResults()[0].getTargets().length == 0) {
            	logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size = 0, check the browse path!");
                logger.trace(result_node.get().getResults()[0].getStatusCode().toString());
                return null;
            }
            Object nodeIdentifier = result_node.get().getResults()[0].getTargets()[0].getTargetId().getIdentifier();
            Object parentIdentifier = result_parent.get().getResults()[0].getTargets()[0].getTargetId().getIdentifier();
            UShort nodeNsIdx = result_node.get().getResults()[0].getTargets()[0].getTargetId().getNamespaceIndex();
            UShort parentNsIdx = result_parent.get().getResults()[0].getTargets()[0].getTargetId().getNamespaceIndex();
            if (nodeIdentifier instanceof String && parentIdentifier instanceof String) {
                return new NodeId[] { new NodeId(parentNsIdx, (String) parentIdentifier),
                        new NodeId(nodeNsIdx, (String) nodeIdentifier) };
            }
            if (nodeIdentifier instanceof UInteger && parentIdentifier instanceof UInteger) {
                return new NodeId[] { new NodeId(parentNsIdx, (UInteger) parentIdentifier),
                        new NodeId(nodeNsIdx, (UInteger) nodeIdentifier) };
            }
            if (nodeIdentifier instanceof UInteger && parentIdentifier instanceof String) {
                return new NodeId[] { new NodeId(parentNsIdx, (String) parentIdentifier),
                        new NodeId(nodeNsIdx, (UInteger) nodeIdentifier) };
            }
            if (nodeIdentifier instanceof String && parentIdentifier instanceof UInteger) {
                return new NodeId[] { new NodeId(parentNsIdx, (UInteger) parentIdentifier),
                        new NodeId(nodeNsIdx, (String) nodeIdentifier) };
            } else {
            	logger.error("NodeId identifier is not neither String, nor int");
                return null;
            }
        } catch (Exception e) {
        	logger.error("Exception in translateBrowsePathToNodeId", e);
        }
        return null;
    }

}
