/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.qpid.example;

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

import javax.jms.Connection;

import org.apache.qpid.client.AMQConnection;

public class OptionParser
{    
    static final Option BROKER = new Option("b",
            "broker",
            "connect to specified broker",
            "USER:PASS@HOST:PORT",
            "guest:guest@localhost:5672",
            String.class);        
        
    static final Option HELP = new Option("h",
            "help",
            "show this help message and exit",
            null,
            null,
            Boolean.class);
    
    static final Option TIMEOUT = new Option("t",
            "timeout",
            "timeout in seconds to wait before exiting",
            "TIMEOUT",
            "0",
            Integer.class);
    
    static final Option CON_OPTIONS = new Option(null,
            "con-option",
            "JMS Connection URL options. Ex sync_ack=true sync_publish=all ",
            "NAME=VALUE",
            null,
            String.class);
    
    
    static final Option BROKER_OPTIONS = new Option(null,
            "broker-option",
            "JMS Broker URL options. Ex ssl=true sasl_mechs=GSSAPI ",
            "NAME=VALUE",
            null,
            String.class);
    
    
    private Map<String,Object> optMap = new HashMap<String,Object>();
    private static final List<Option> optDefs = new ArrayList<Option>();

    private static final String CLIENTID = "test";
    
    private String usage;
    private String desc;
    private String address;
    
    public OptionParser(String[] args, String usage, String desc)
    {   
        this.usage = usage;
        this.desc  = desc;
        
        if (args.length == 0 || 
           (args.length == 1 && (args[0].equals("-h") || args[0].equals("--help"))))
        {
            printHelp();
        }
        
        address = args[args.length -1];
        String[] ops = new String[args.length -1];
        System.arraycopy(args, 0, ops, 0, ops.length);        
        parseOpts(ops);
        
        System.out.println(optMap);
        
        if (isHelp())
        {
            printHelp();
        }
    }
    
    public boolean isHelp()
    {
        return optMap.containsKey("h") || optMap.containsKey("help");
    }
    
    public void printHelp()
    {
        System.out.println(String.format("%s\n",usage));
        System.out.println(String.format("%s\n",desc));
        System.out.println(String.format("%s\n","Options:"));
        
        for (Option op : optDefs)
        {  
           String valueLabel = op.getValueLabel() != null ? "=" + op.getValueLabel() : ""; 
           String shortForm = op.getShortForm() != null ? "-" + op.getShortForm() + valueLabel : "";
           String longForm = op.getLongForm() != null ? "--" + op.getLongForm() + valueLabel : "";
           String desc = op.getDesc();
           String defaultValue = op.getDefaultValue() != null ? 
                   " (default " + op.getDefaultValue() + ")" : "";
           
           if (!shortForm.equals(""))
           {
               longForm = shortForm + ", " + longForm;
           }
           System.out.println(
                   String.format("%-54s%s%s", longForm,desc,defaultValue));
        }
        
        System.exit(0);
    }
    
    private void parseOpts(String[] args)
    {   
        String prevOpt = null;
        for(String op: args)
        {
            // covers both -h and --help formats
            if (op.startsWith("-"))
            {
                String key = op.substring(op.startsWith("--")? 2:1 ,
                                         (op.indexOf('=') > 0) ? 
                                            op.indexOf('='):
                                            op.length());
                
                boolean match = false;
                for (Option option: optDefs)
                {
                    
                    if ((op.startsWith("-") && option.getShortForm() != null && option.getShortForm().equals(key)) ||
                        (op.startsWith("--") && option.getLongForm() != null && option.getLongForm().equals(key)) )
                    {
                        match = true;
                        break;
                    }
                }
                
                if (!match) 
                { 
                    System.out.println(op + " is not a valid option"); 
                    System.exit(0);
                }                    
                
                if (op.indexOf('=') > 0)
                {
                    String val = extractValue(op.substring(op.indexOf('=')+1));
                    if (optMap.containsKey(key))
                    {
                        optMap.put(key, optMap.get(key) + "," + val);
                    }
                    else
                    {
                        optMap.put(key, val);
                    }
                }
                else
                {
                    if (! optMap.containsKey(key)){ optMap.put(key, ""); }
                    prevOpt = key;
                }
            }
            else if (prevOpt != null) // this is to catch broker localhost:5672 instead broker=localhost:5672
            {
                String val = extractValue(op);
                if (optMap.containsKey(prevOpt) && !optMap.get(prevOpt).toString().equals(""))
                {
                    optMap.put(prevOpt, optMap.get(prevOpt) + "," + val);
                }
                else
                {
                    optMap.put(prevOpt, val);
                }
                prevOpt = null;
            }
            else
            {
                System.out.println(optMap);
                throw new IllegalArgumentException(op + " is not a valid option");
            }
        }
    }
    
    private String extractValue(String op)
    {
        if (op.startsWith("'"))
        {
            if (!op.endsWith("'")) 
            {
                throw new IllegalArgumentException(" The option " + op + " needs to be inside quotes");
            }
            
            return op.substring(1,op.length() -1);
        }
        else
        {
            return op;
        }
    }
    
    protected boolean containsOp(Option op)
    {
        return optMap.containsKey(op.getShortForm()) || optMap.containsKey(op.getLongForm());
    }
    
    protected String getOp(Option op)
    {
        if (optMap.containsKey(op.getShortForm()))
        {
            return (String)optMap.get(op.getShortForm());
        }
        else if (optMap.containsKey(op.getLongForm()))
        {
            return (String)optMap.get(op.getLongForm());
        }
        else
        {
            return op.getDefaultValue();
        }           
    }    

    protected Connection createConnection() throws Exception
    {
        StringBuffer buf;
        buf = new StringBuffer();       
        buf.append("amqp://");
        String userPass = "guest:guest";
        String broker = "localhost:5672";
        if(containsOp(BROKER))
        {
            try
            {
                String b = getOp(BROKER);
                userPass = b.substring(0,b.indexOf('@'));
                broker = b.substring(b.indexOf('@')+1);
            }    
            catch (StringIndexOutOfBoundsException e)
            {
                Exception ex = new Exception("Error parsing broker string " + getOp(BROKER));
                ex.initCause(e);
                throw ex;
            }   
            
        }
        
        if(containsOp(BROKER_OPTIONS))
        {
            String bOps = getOp(BROKER_OPTIONS);
            bOps = bOps.replaceAll(",", "'&");
            bOps = bOps.replaceAll("=", "='");
            broker = broker + "?" + bOps + "'";
        }
        buf.append(userPass);
        buf.append("@");
        buf.append(CLIENTID);
        buf.append("/?brokerlist='tcp://");
        buf.append(broker).append("'");
        if(containsOp(CON_OPTIONS))
        {
            String bOps = getOp(CON_OPTIONS);
            bOps = bOps.replaceAll(",", "'&");
            bOps = bOps.replaceAll("=", "='");
            buf.append("&").append(bOps).append("'");
        }
        
        Connection con = new AMQConnection(buf.toString());
        return con;
    }

    public static void addOption(Option opt)
    {
        optDefs.add(opt);
    }

    protected String getAddress()
    {
        return address;
    }

    static class Option
    {
        private final String shortForm;
        private final String longForm;
        private final String desc;
        private final String valueLabel;
        private final String defaultValue;
        private final Class type;
        
        public Option(String shortForm, String longForm, String desc,
                      String valueLabel, String defaultValue, Class type)
        {
            this.shortForm = shortForm;
            this.longForm = longForm;
            this.defaultValue = defaultValue;
            this.type = type;
            this.desc = desc;
            this.valueLabel = valueLabel;
        }

        public String getShortForm()
        {
            return shortForm;
        }
        
        public String getLongForm()
        {
            return longForm;
        }
        
        public String getDefaultValue()
        {
            return defaultValue;
        }
        
        public Class getType()
        {
            return type;
        }    
        
        public String getDesc()
        {
            return desc;
        }
        
        public String getValueLabel()
        {
            return valueLabel;
        }
    }
}
