// Copyright 2017 Intermodalics All Rights Reserved.
package eu.intermodalics.nodelet_manager;

import android.util.Log;

import org.ros.namespace.GraphName;
import org.ros.node.NativeNodeMain;
import org.ros.node.Node;

import java.util.Arrays;
import java.util.List;

public class TangoNodeletManager extends NativeNodeMain {
    // TODO(mcopejans) Move constants below to separate package.
    public static final int ROS_CONNECTION_ERROR = 1;
    public static final String ROS_CONNECTION_FAILURE_ERROR_MSG = "ECONNREFUSED";
    public static final String ROS_CONNECTION_UNREACHABLE_ERROR_MSG = "ENETUNREACH";
    public static final String ROS_CONNECTION_TIMEOUT_ERROR_MSG = "No response after waiting for 10000 milliseconds.";
    public static final String ROS_WRONG_HOST_NAME_ERROR_MSG = "No address associated with hostname";

    // Node specific.
    public static final String NODE_NAME = "tango";
    public static final String DEFAULT_LIB_NAME = "nodelet_manager";

    private List<String> mErrorMessages;
    private CallbackListener mCallbackListener;

    public TangoNodeletManager() {
        super(DEFAULT_LIB_NAME);
        mErrorMessages = Arrays.asList(
                ROS_CONNECTION_FAILURE_ERROR_MSG,
                ROS_CONNECTION_UNREACHABLE_ERROR_MSG,
                ROS_CONNECTION_TIMEOUT_ERROR_MSG,
                ROS_WRONG_HOST_NAME_ERROR_MSG);
    }

    public TangoNodeletManager(String libName) {
        super(libName);
    }

    /**
     * Static helper function which loads shared library to link native functions.
     */
    public static final boolean loadNodeletManagerSharedLibrary() {
        try {
            System.loadLibrary(DEFAULT_LIB_NAME);
        } catch (UnsatisfiedLinkError e) {
            Log.e(TangoNodeletManager.class.getName(),
                    "Error loading shared library: " + DEFAULT_LIB_NAME, e);
            return false;
        }
        return true;
    }

    @Override
    public native int execute(String rosMasterUri, String rosHostName, String rosNodeName, String[] remappingArguments);

    @Override
    public native int shutdown();

    public interface CallbackListener {
        void onNodeletManagerError(int returnCode);
    }

    public void attachCallbackListener(CallbackListener callbackListener) {
        mCallbackListener = callbackListener;
    }

    @Override
    public GraphName getDefaultNodeName() {
        return GraphName.of(NODE_NAME);
    }

    @Override
    public void onError(Node node, Throwable throwable) {
        super.onError(node, throwable);
        for (String errorMessage : mErrorMessages) {
            if (throwable.getMessage().contains(errorMessage)) {
                executeOnErrorHook(ROS_CONNECTION_ERROR);
                return;
            }
        }
        if (this.executeReturnCode != 0) {
            executeOnErrorHook(this.executeReturnCode);
        }
    }

    private void executeOnErrorHook(int returnCode) {
        if (mCallbackListener != null) {
            mCallbackListener.onNodeletManagerError(returnCode);
        }
    }
}

@@ -332,2749 +332,1052 @@
  // 
-TODO(mcopejans) Move constants below to separate package.%0A    public static final int ROS_CONNECTION_ERROR = 1;%0A    public static final String ROS_CONNECTION_FAILURE_ERROR_MSG = %22ECONNREFUSED%22;%0A    public static final String ROS_CONNECTION_UNREACHABLE_ERROR_MSG = %22ENETUNREACH%22;%0A    public static final String ROS_CONNECTION_TIMEOUT_ERROR_MSG = %22No response after waiting for 10000 milliseconds.%22;%0A    public static final String ROS_WRONG_HOST_NAME_ERROR_MSG = %22No address associated with hostname%22;%0A%0A    // Node specific.%0A    public static final String NODE_NAME = %22tango%22;%0A    public static final String DEFAULT_LIB_NAME = %22nodelet_manager%22;%0A%0A    private List%3CString%3E mErrorMessages;%0A    private CallbackListener mCallbackListener;%0A%0A    public TangoNodeletManager() %7B%0A        super(DEFAULT_LIB_NAME);%0A        mErrorMessages = Arrays.asList(%0A                ROS_CONNECTION_FAILURE_ERROR_MSG,%0A                ROS_CONNECTION_UNREACHABLE_ERROR_MSG,%0A                ROS_CONNECTION_TIMEOUT_ERROR_MSG,%0A                ROS_WRONG_HOST_NAME_ERROR_MSG);%0A    %7D%0A%0A    public TangoNodeletManager(String libName) %7B%0A        super(libName);%0A    %7D%0A%0A    /**%0A     * Static helper function which loads shared library to link native functions.%0A     */%0A    public static final boolean loadNodeletManagerSharedLibrary() %7B%0A        try %7B%0A            System.loadLibrary(DEFAULT_LIB_NAME);%0A        %7D catch (UnsatisfiedLinkError e) %7B%0A            Log.e(TangoNodeletManager.class.getName(),%0A                    %22Error loading shared library: %22 + DEFAULT_LIB_NAME, e);%0A            return false;%0A        %7D%0A        return true;%0A    %7D%0A%0A    @Override%0A    public native int execute(String rosMasterUri, String rosHostName, String rosNodeName, String%5B%5D remappingArguments);%0A%0A    @Override%0A    public native int shutdown();%0A%0A    public interface CallbackListener %7B%0A        void onNodeletManagerError(int returnCode);%0A    %7D%0A%0A    public void attachCallbackListener(CallbackListener callbackListener) %7B%0A        mCallbackListener = callbackListener;%0A    %7D%0A%0A    @Override%0A    public GraphName getDefaultNodeName() %7B%0A        return GraphName.of(NODE_NAME);%0A    %7D%0A%0A    @Override%0A    public void onError(Node node, Throwable throwable) %7B%0A        super.onError(node, throwable);%0A        for (String errorMessage : mErrorMessages) %7B%0A            if (throwable.getMessage().contains(errorMessage)) %7B%0A                executeOnErrorHook(ROS_CONNECTION_ERROR);%0A                return;%0A            %7D%0A        %7D%0A        if (this.executeReturnCode != 0) %7B%0A            executeOnErrorHook(this.executeReturnCode);%0A        %7D%0A    %7D%0A%0A    private void executeOnErrorHook(int returnCode) %7B%0A        if (mCallbackListener != null) %7B%0A            mCallbackListener.onNodeletManagerError(returnCode);%0A        %7D
+Node specific.%0A    public static final String NODE_NAME = %22tango%22;%0A    public static final String DEFAULT_LIB_NAME = %22nodelet_manager%22;%0A%0A    public TangoNodeletManager() %7B%0A        super(DEFAULT_LIB_NAME);%0A    %7D%0A%0A    public TangoNodeletManager(String libName) %7B%0A        super(libName);%0A    %7D%0A%0A    /**%0A     * Static helper function which loads shared library to link native functions.%0A     */%0A    public static final boolean loadNodeletManagerSharedLibrary() %7B%0A        try %7B%0A            System.loadLibrary(DEFAULT_LIB_NAME);%0A        %7D catch (UnsatisfiedLinkError e) %7B%0A            Log.e(TangoNodeletManager.class.getName(),%0A                    %22Error loading shared library: %22 + DEFAULT_LIB_NAME, e);%0A            return false;%0A        %7D%0A        return true;%0A    %7D%0A%0A    @Override%0A    public native int execute(String rosMasterUri, String rosHostName, String rosNodeName, String%5B%5D remappingArguments);%0A%0A    @Override%0A    public native int shutdown();%0A%0A    @Override%0A    public GraphName getDefaultNodeName() %7B%0A        return GraphName.of(NODE_NAME);
 %0A   

Remove ros error hook from nodelet manager