/*
 * Copyright (C) 2013 The enviroCar project
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.envirocar.server.event;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.X509Certificate;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.envirocar.server.core.entities.Track;

import org.envirocar.server.core.event.CreatedTrackEvent;
import org.envirocar.server.rest.MediaTypes;
import org.envirocar.server.rest.encoding.JSONEntityEncoder;

import org.envirocar.server.rest.rights.AccessRightsImpl;

@Singleton
public class HTTPPushListener {
    //TODO make configurable
    private static final String host =
            "http://geoprocessing.demo.52north.org:8081/simplebroker/";
    private static final Logger logger = LoggerFactory
            .getLogger(HTTPPushListener.class);
    public static final AccessRightsImpl DEFAULT_ACCESS_RIGHTS =
            new AccessRightsImpl();
    private final HttpClient client;
    private final JSONEntityEncoder<Track> encoder;
    private final ObjectWriter writer;

    @Inject
    public HTTPPushListener(JSONEntityEncoder<Track> encoder,
                            ObjectWriter writer) throws Exception {
        this.client = createClient();
        this.encoder = encoder;
        this.writer = writer;
    }

    @Subscribe
    public void onCreatedTrackEvent(CreatedTrackEvent e) {
        pushNewTrack(e.getTrack());
    }

    private synchronized void pushNewTrack(Track track) {
        HttpResponse resp = null;
        try {
            ObjectNode jsonTrack = encoder
                    .encodeJSON(track, DEFAULT_ACCESS_RIGHTS,
                                MediaTypes.TRACK_TYPE);
            String content = writer.writeValueAsString(jsonTrack);
            logger.debug("Entity: {}", content);
            HttpEntity entity = new StringEntity(
                    content, ContentType.create(MediaTypes.TRACK));
            HttpPost hp = new HttpPost(host);
            hp.setEntity(entity);
            resp = this.client.execute(hp);
        } catch (ClientProtocolException e) {
            logger.warn(e.getMessage(), e);
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
        } finally {
            if (resp != null) {
                try {
                    EntityUtils.consume(resp.getEntity());
                } catch (IOException e) {
                    logger.warn(e.getMessage());
                }
            }
        }
    }

    private HttpClient createClient() throws UnrecoverableKeyException,
                                             KeyManagementException,
                                             KeyStoreException,
                                             NoSuchAlgorithmException {
        SSLSocketFactory sslsf = new SSLSocketFactory(new TrustStrategy() {
            @Override
            public boolean isTrusted(final X509Certificate[] chain,
                                     String authType) {
                //FIXME kind of bad practice...
                return true;
            }
        });
        Scheme httpsScheme2 = new Scheme("https", 443, sslsf);
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(httpsScheme2);

        BasicClientConnectionManager cm =
                new BasicClientConnectionManager(schemeRegistry);

        return new DefaultHttpClient(cm);
    }
}

@@ -962,51 +962,8 @@
 ion;
-%0Aimport java.security.cert.X509Certificate;
 %0A%0Aim
@@ -1181,199 +1181,8 @@
 st;%0A
-import org.apache.http.conn.scheme.Scheme;%0Aimport org.apache.http.conn.scheme.SchemeRegistry;%0Aimport org.apache.http.conn.ssl.SSLSocketFactory;%0Aimport org.apache.http.conn.ssl.TrustStrategy;%0A
 impo
@@ -1322,71 +1322,8 @@
 nt;%0A
-import org.apache.http.impl.conn.BasicClientConnectionManager;%0A
 impo
@@ -4142,615 +4142,8 @@
 n %7B%0A
-        SSLSocketFactory sslsf = new SSLSocketFactory(new TrustStrategy() %7B%0A            @Override%0A            public boolean isTrusted(final X509Certificate%5B%5D chain,%0A                                     String authType) %7B%0A                //FIXME kind of bad practice...%0A                return true;%0A            %7D%0A        %7D);%0A        Scheme httpsScheme2 = new Scheme(%22https%22, 443, sslsf);%0A        SchemeRegistry schemeRegistry = new SchemeRegistry();%0A        schemeRegistry.register(httpsScheme2);%0A%0A        BasicClientConnectionManager cm =%0A                new BasicClientConnectionManager(schemeRegistry);%0A%0A
     
@@ -4179,10 +4179,8 @@
 ent(
-cm
 );%0A 

remove SSL ignorance and correpsonding Scheme registry