//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.monitor.integration;

import static java.lang.Integer.parseInt;
import static java.lang.System.getProperty;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.util.BytesContentProvider;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.monitor.JMXMonitor;
import org.eclipse.jetty.monitor.jmx.EventNotifier;
import org.eclipse.jetty.monitor.jmx.EventState;
import org.eclipse.jetty.monitor.jmx.EventState.TriggerState;
import org.eclipse.jetty.monitor.jmx.EventTrigger;
import org.eclipse.jetty.monitor.jmx.MonitorAction;
import org.eclipse.jetty.monitor.triggers.AggregateEventTrigger;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;

public class JavaMonitorAction extends MonitorAction
{
    private static final Logger LOG = Log.getLogger(JavaMonitorAction.class);

    private final HttpClient _client;
    
    private final String _url;
    private final String _uuid;
    private final String _appid;
    
    private String _srvip;
    private String _session;
    
    /* ------------------------------------------------------------ */
    public JavaMonitorAction(EventNotifier notifier, String url, String uuid, String appid, long pollInterval)
        throws Exception
    {
        super(new AggregateEventTrigger(),notifier,pollInterval);
        
        _url = url;
        _uuid = uuid;
        _appid = appid;
        
        QueuedThreadPool executor = new QueuedThreadPool();
        executor.setName(executor.getName() + "-monitor");
        _client = new HttpClient();
        _client.setExecutor(executor);
        
        try
        {
            _client.start();
            _srvip = getServerIP();
        }
        catch (Exception ex)
        {
            LOG.debug(ex);
        }
        
        sendData(new Properties());
     }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.monitor.jmx.MonitorAction#execute(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long)
     */
    @Override
    public void execute(EventTrigger trigger, EventState<?> state, long timestamp)
    {
        exec(trigger, state, timestamp);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param trigger
     * @param state
     * @param timestamp
     */
    private <T> void exec(EventTrigger trigger, EventState<T> state, long timestamp)
    {
        Collection<TriggerState<T>> trs = state.values();
        
        Properties data = new Properties();
        for (TriggerState<T> ts :  trs)
        {
            Object value = ts.getValue();

            StringBuffer buffer = new StringBuffer();
            buffer.append(value == null ? "" : value.toString());
            buffer.append("|");
            buffer.append(getClassID(value));
            buffer.append("||");
            buffer.append(ts.getDescription());
            
            data.setProperty(ts.getID(), buffer.toString());
            
            try
            {
                sendData(data);
            }
            catch (Exception ex)
            {
                LOG.debug(ex);
            }
        }
     }
    
    /* ------------------------------------------------------------ */
    /**
     * @param data
     * @throws Exception 
     */
    private void sendData(Properties data)
        throws Exception
    {
        data.put("account", _uuid);
        data.put("appserver", "Jetty");
        data.put("localIp", _srvip);
        if (_appid == null)
            data.put("lowestPort", getHttpPort());
        else
            data.put("lowestPort", _appid);
        if (_session != null)
            data.put("session", _session);
        
        Properties response = sendRequest(data);
        
        parseResponse(response);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param request
     * @return
     * @throws Exception 
     */
    private Properties sendRequest(Properties request)
        throws Exception
    {
        ByteArrayOutputStream reqStream = null;
        ByteArrayInputStream resStream = null;
        Properties response = null;
    
        try {
            reqStream = new ByteArrayOutputStream();
            request.storeToXML(reqStream,null);
            
            ContentResponse r3sponse = _client.POST(_url)
                .header("Connection","close")
                .content(new BytesContentProvider(reqStream.toByteArray()))
                .send();
            
                        
            if (r3sponse.getStatus() == HttpStatus.OK_200)
            {
                response = new Properties();
                resStream = new ByteArrayInputStream(r3sponse.getContent());
                response.loadFromXML(resStream);               
            }
        }
        finally
        {
            try
            {
                if (reqStream != null)
                    reqStream.close();
            }
            catch (IOException ex)
            {
                LOG.ignore(ex);
            }
            
            try
            {
                if (resStream != null)
                    resStream.close();
            }
            catch (IOException ex)
            {
                LOG.ignore(ex);
            }
        }
        
        return response;    
    }
    
    /* ------------------------------------------------------------ */
    private void parseResponse(Properties response)
    {
        if (response.get("onhold") != null)
            throw new Error("Suspended");
        

        if (response.get("session") != null)
        {
            _session = (String) response.remove("session");

            AggregateEventTrigger trigger = (AggregateEventTrigger)getTrigger();

            String queryString;
            ObjectName[] queryResults;
            for (Map.Entry<Object, Object> entry : response.entrySet())
            {
                String[] values = ((String) entry.getValue()).split("\\|");

                queryString = values[0];
                if (queryString.startsWith("com.javamonitor.openfire"))
                    continue;
                
                if (queryString.startsWith("com.javamonitor"))
                {
                    queryString = "org.eclipse.jetty.monitor.integration:type=javamonitortools,id=0";
                }
                
                queryResults = null;
                try
                {
                    queryResults = queryNames(queryString);
                }
                catch (IOException e)
                {
                    LOG.debug(e);
                }
                catch (MalformedObjectNameException e)
                {
                    LOG.debug(e);
                }
                
                if (queryResults != null)
                {
                    int idx = 0;
                    for(ObjectName objName : queryResults)
                    {
                        String id = entry.getKey().toString()+(idx == 0 ? "" : ":"+idx);
                        String name = queryString.equals(objName.toString()) ? "" : objName.toString();
                        boolean repeat = Boolean.parseBoolean(values[2]);
                        trigger.add(new JavaMonitorTrigger(objName, values[1], id, name, repeat));
                    }   
                }
           }
        }
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param value
     * @return
     */
    private int getClassID(final Object value)
    {
        if (value == null)
            return 0;
        
        if (value instanceof Byte || 
            value instanceof Short ||
            value instanceof Integer ||
            value instanceof Long)
            return 1;
            
        if (value instanceof Float ||
            value instanceof Double)
            return 2;
        
        if (value instanceof Boolean)
            return 3;

        return 4; // String
    }

    /* ------------------------------------------------------------ */
    /**
     * @return
     * @throws Exception 
     */
    private String getServerIP()
        throws Exception
    {
        Socket s = null;
        try {
            if (getProperty("http.proxyHost") != null)
            {
                s = new Socket(getProperty("http.proxyHost"),
                               parseInt(getProperty("http.proxyPort", "80")));
            } 
            else
            {
                int port = 80;
                
                URL url = new URL(_url);
                if (url.getPort() != -1) {
                    port = url.getPort();
                }
                s = new Socket(url.getHost(), port);
            }
            return s.getLocalAddress().getHostAddress();
        }
        finally
        {
            try
            {
                if (s != null)
                    s.close();
            } 
            catch (IOException ex)
            {
                LOG.ignore(ex);
            }
        }
    }
    
    /* ------------------------------------------------------------ */
    public Integer getHttpPort() 
    {       
        Collection<ObjectName> connectors = null;
        MBeanServerConnection service;
        try
        {
            service = JMXMonitor.getServiceConnection();

            connectors = service.queryNames(new ObjectName("org.eclipse.jetty.nio:type=selectchannelconnector,*"), null);
            if (connectors != null && connectors.size() > 0)
            {
                Integer lowest = Integer.MAX_VALUE;
                for (final ObjectName connector : connectors) {
                    lowest = (Integer)service.getAttribute(connector, "port");
                }
        
                if (lowest < Integer.MAX_VALUE)
                    return lowest;
            }
        }
        catch (Exception ex)
        {
            LOG.debug(ex);
        }
        
        return 0;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param param
     * @return
     * @throws IOException
     * @throws NullPointerException 
     * @throws MalformedObjectNameException 
     */
    private ObjectName[] queryNames(ObjectName param) 
        throws IOException, MalformedObjectNameException
    {
        ObjectName[] result = null;
        
        MBeanServerConnection connection = JMXMonitor.getServiceConnection();
        Set names = connection.queryNames(param, null);
        if (names != null && names.size() > 0)
        {
            result = new ObjectName[names.size()];
            
            int idx = 0;
            for(Object name : names)
            {
                if (name instanceof ObjectName)
                    result[idx++] = (ObjectName)name;
                else
                    result[idx++] = new ObjectName(name.toString());
            }
        }
        
        return result;
    }
    
    private ObjectName[] queryNames(String param) 
        throws IOException, MalformedObjectNameException
    {
        return queryNames(new ObjectName(param));
    }

 }
