class SCTPShellExecutor implements ShellExecutor {

    @Override
    public String execute(String[] args) {
        try {
            if (this.sctpManagements.size() == 0) {
                return M3UAOAMMessages.NO_SCTP_MANAGEMENT_BEAN;
            }

            if (args.length < 2 || args.length > 13) {
                // any command will have atleast 3 args
                return M3UAOAMMessages.INVALID_COMMAND;
            }

            if (args[1] == null) {
                return M3UAOAMMessages.INVALID_COMMAND;
            }

            if (args[1].equals("server")) {
                if (args.length < 3 ){
                    return M3UAOAMMessages.INVALID_COMMAND;
                }

                String command = args[2];

                if (command == null) {
                    return M3UAOAMMessages.INVALID_COMMAND;
                } else if (command.equals("create")) {
                    // command is sctp server create <sever-name> <host-ip> <host-port> sockettype <socket-type> stackname
                    // <stack-name>

                    if (args.length < 6 || args.length > 10) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String serverName = args[3];
                    if (serverName == null) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String hostAddress = args[4];
                    if (hostAddress == null) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String[] hostAddresses = hostAddress.split(",");
                    String primaryAddress = hostAddresses[0];
                    String[] secondaryAddresses = null;

                    if (hostAddresses.length > 1) {
                        secondaryAddresses = new String[(hostAddresses.length - 1)];
                        for (int i = 0; i < secondaryAddresses.length; i++) {
                            secondaryAddresses[i] = hostAddresses[(i + 1)];
                        }
                    }

                    int hostPort = Integer.parseInt(args[5]);

                    IpChannelType ipChnnelType = null;

                    String sctpStackName = null;

                    int i = 6;
                    if (args.length > 6) {

                        while (i < args.length) {

                            if (args[i].equals("stackname")) {
                                sctpStackName = args[i + 1];

                                Management sctpManagementtmp = this.sctpManagements.get(sctpStackName);

                                if (sctpManagementtmp == null) {
                                    return String.format(M3UAOAMMessages.NO_SCTP_MANAGEMENT_BEAN_FOR_NAME, sctpStackName);
                                }

                                this.sctpManagement = sctpManagementtmp;
                            } else if (args[i].equals("sockettype")) {
                                ipChnnelType = IpChannelType.getInstance(args[i + 1]);
                            }

                            i = i + 2;

                        }// while loop
                    }

                    this.setDefaultValue();

                    if (ipChnnelType == null) {
                        ipChnnelType = IpChannelType.SCTP;
                    }

                    this.sctpManagement.addServer(serverName, primaryAddress, hostPort, ipChnnelType, secondaryAddresses);

                    return String.format(SCTPOAMMessages.ADD_SERVER_SUCCESS, serverName, this.sctpManagement.getName());

                } else if (command.equals("destroy")) {
                    // sctp server destroy <sever-name> stackname <stack-name>
                    if (args.length < 4) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String serverName = args[3];
                    if (serverName == null) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String sctpStackName = null;
                    if (args.length > 4) {
                        if (!args[4].equals("stackname")) {
                            return M3UAOAMMessages.INVALID_COMMAND;
                        }

                        sctpStackName = args[5];
                        Management sctpManagementtmp = this.sctpManagements.get(sctpStackName);

                        if (sctpManagementtmp == null) {
                            return String.format(M3UAOAMMessages.NO_SCTP_MANAGEMENT_BEAN_FOR_NAME, sctpStackName);
                        }

                        this.sctpManagement = sctpManagementtmp;
                    } else {
                        this.setDefaultValue();
                    }

                    this.sctpManagement.removeServer(serverName);
                    return String.format(SCTPOAMMessages.REMOVE_SERVER_SUCCESS, serverName, this.sctpManagement.getName());

                } else if (command.equals("start")) {
                    // sctp server start <sever-name> stackname <stack-name>

                    if (args.length < 4) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String serverName = args[3];
                    if (serverName == null) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String sctpStackName = null;
                    if (args.length > 4) {
                        if (!args[4].equals("stackname")) {
                            return M3UAOAMMessages.INVALID_COMMAND;
                        }

                        sctpStackName = args[5];
                        Management sctpManagementtmp = this.sctpManagements.get(sctpStackName);

                        if (sctpManagementtmp == null) {
                            return String.format(M3UAOAMMessages.NO_SCTP_MANAGEMENT_BEAN_FOR_NAME, sctpStackName);
                        }

                        this.sctpManagement = sctpManagementtmp;
                    } else {
                        this.setDefaultValue();
                    }

                    this.sctpManagement.startServer(serverName);
                    return String.format(SCTPOAMMessages.START_SERVER_SUCCESS, serverName, this.sctpManagement.getName());
                } else if (command.equals("stop")) {
                    // sctp server stop <sever-name> stackname <stack-name>

                    if (args.length < 4) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String serverName = args[3];
                    if (serverName == null) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String sctpStackName = null;
                    if (args.length > 4) {
                        if (!args[4].equals("stackname")) {
                            return M3UAOAMMessages.INVALID_COMMAND;
                        }

                        sctpStackName = args[5];
                        Management sctpManagementtmp = this.sctpManagements.get(sctpStackName);

                        if (sctpManagementtmp == null) {
                            return String.format(M3UAOAMMessages.NO_SCTP_MANAGEMENT_BEAN_FOR_NAME, sctpStackName);
                        }

                        this.sctpManagement = sctpManagementtmp;
                    } else {
                        this.setDefaultValue();
                    }

                    this.sctpManagement.stopServer(serverName);
                    return String.format(SCTPOAMMessages.STOP_SERVER_SUCCESS, serverName, this.sctpManagement.getName());
                } else if (command.equals("show")) {
                    return this.showServers(args);
                }

                return M3UAOAMMessages.INVALID_COMMAND;

            } else if (args[1].equals("association")) {
                if (args.length < 3 ){
                    return M3UAOAMMessages.INVALID_COMMAND;
                }

                String command = args[2];

                if (command == null) {
                    return M3UAOAMMessages.INVALID_COMMAND;
                } else if (command.equals("create")) {
                    // sctp association create <assoc-name> <CLIENT | SERVER> <server-name> <peerip> <peer-port> <host- ip>
                    // <host-port> sockettype <socket-type> stackname <stack-name>

                    if (args.length < 8 || args.length > 13) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String assocName = args[3];
                    if (assocName == null) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String type = args[4];
                    if (type == null) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    } else if (type.equals("CLIENT")) {
                        if (args.length < 9) {
                            return M3UAOAMMessages.INVALID_COMMAND;
                        }

                        String peerIp = args[5];
                        int peerPort = Integer.parseInt(args[6]);

                        String hostIp = args[7];

                        String[] hostAddresses = hostIp.split(",");
                        String primaryAddress = hostAddresses[0];
                        String[] secondaryAddresses = null;

                        if (hostAddresses.length > 1) {
                            secondaryAddresses = new String[(hostAddresses.length - 1)];
                            for (int i = 0; i < secondaryAddresses.length; i++) {
                                secondaryAddresses[i] = hostAddresses[(i + 1)];
                            }
                        }

                        int hostPort = Integer.parseInt(args[8]);

                        IpChannelType ipChnnelType = null;

                        String sctpStackName = null;

                        int i = 9;
                        if (args.length > 9) {

                            while (i < args.length) {

                                if (args[i].equals("stackname")) {
                                    sctpStackName = args[i + 1];

                                    Management sctpManagementtmp = this.sctpManagements.get(sctpStackName);

                                    if (sctpManagementtmp == null) {
                                        return String.format(M3UAOAMMessages.NO_SCTP_MANAGEMENT_BEAN_FOR_NAME, sctpStackName);
                                    }

                                    this.sctpManagement = sctpManagementtmp;
                                } else if (args[i].equals("sockettype")) {
                                    ipChnnelType = IpChannelType.getInstance(args[i + 1]);
                                }

                                i = i + 2;

                            }// while loop
                        }

                        this.setDefaultValue();

                        if (ipChnnelType == null) {
                            ipChnnelType = IpChannelType.SCTP;
                        }

                        this.sctpManagement.addAssociation(primaryAddress, hostPort, peerIp, peerPort, assocName, ipChnnelType,
                                secondaryAddresses);

                        return String.format(SCTPOAMMessages.ADD_CLIENT_ASSOCIATION_SUCCESS, assocName,
                                this.sctpManagement.getName());
                    } else if (type.equals("SERVER")) {
                        String serverName = args[5];

                        String peerIp = args[6];
                        int peerPort = Integer.parseInt(args[7]);

                        IpChannelType ipChnnelType = null;

                        String sctpStackName = null;

                        int i = 8;
                        if (args.length > 8) {

                            while (i < args.length) {

                                if (args[i].equals("stackname")) {
                                    sctpStackName = args[i + 1];

                                    Management sctpManagementtmp = this.sctpManagements.get(sctpStackName);

                                    if (sctpManagementtmp == null) {
                                        return String.format(M3UAOAMMessages.NO_SCTP_MANAGEMENT_BEAN_FOR_NAME, sctpStackName);
                                    }

                                    this.sctpManagement = sctpManagementtmp;
                                } else if (args[i].equals("sockettype")) {
                                    ipChnnelType = IpChannelType.getInstance(args[i + 1]);
                                }

                                i = i + 2;

                            }// while loop
                        }

                        if (this.sctpManagement == null) {
                            this.setDefaultValue();
                        }

                        if (ipChnnelType == null) {
                            ipChnnelType = IpChannelType.SCTP;
                        }

                        this.sctpManagement.addServerAssociation(peerIp, peerPort, serverName, assocName, ipChnnelType);
                        return String.format(SCTPOAMMessages.ADD_SERVER_ASSOCIATION_SUCCESS, assocName,
                                this.sctpManagement.getName());
                    }

                    return M3UAOAMMessages.INVALID_COMMAND;

                } else if (command.equals("destroy")) {
                    // sctp association destroy <assoc-name> stackname <stack-name>

                    if (args.length < 4) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String assocName = args[3];
                    if (assocName == null) {
                        return M3UAOAMMessages.INVALID_COMMAND;
                    }

                    String sctpStackName = null;

                    if (args.length > 4) {
                        if (!args[4].equals("stackname")) {
                            return M3UAOAMMessages.INVALID_COMMAND;
                        }

                        sctpStackName = args[5];
                        Management sctpManagementtmp = this.sctpManagements.get(sctpStackName);

                        if (sctpManagementtmp == null) {
                            return String.format(M3UAOAMMessages.NO_SCTP_MANAGEMENT_BEAN_FOR_NAME, sctpStackName);
                        }

                        this.sctpManagement = sctpManagementtmp;
                    } else {
                        this.setDefaultValue();
                    }

                    this.sctpManagement.removeAssociation(assocName);
                    return String.format(SCTPOAMMessages.REMOVE_ASSOCIATION_SUCCESS, assocName, this.sctpManagement.getName());

                } else if (command.equals("show")) {
                    return this.showAssociations(args);
                }

                return M3UAOAMMessages.INVALID_COMMAND;
            } else if (args[1].equals("set")) {
                return this.manageSet(args);
            } else if (args[1].equals("get")) {
                return this.manageGet(args);
            }

            return M3UAOAMMessages.INVALID_COMMAND;
        } catch (Exception e) {
            logger.error(String.format("Error while executing comand %s", Arrays.toString(args)), e);
            return e.toString();
        } catch (Throwable t) {
            logger.error(String.format("Error while executing comand %s", Arrays.toString(args)), t);
            return t.toString();
        }
    }

}