package de.duehl.html.download.logic;

/*
 * Copyright 2017 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;

import de.duehl.basics.logging.Logger;
import de.duehl.html.download.data.DownloadParameters;
import de.duehl.html.download.data.RedirectHandling;
import de.duehl.html.download.proxy.Proxy;
import de.duehl.html.download.proxy.RotatingProxies;

/**
 * Diese Klasse erstellt einen Apache ClosableHttpClient für den Download.
 *
 * Links siehe InternalDownloader.
 *
 * @version 1.01     2017-06-21
 * @author Christian Dühl
 */

public class HttpClientCreator {

    /** User Agent von Firefox 53 laut http://www.whoishostingthis.com/tools/user-agent/ */
    private static final String USER_AGENT =
            "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0";
            //"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) "
            //        + "Chrome/18.0.1003.1 Safari/535.19 Awesomium/1.7.1";

    /** Die Parameter für den Download. */
    private final DownloadParameters parameters;

    /**
     * Konstruktor.
     *
     * @param parameters
     *            Die Parameter für den Download.
     */
    public HttpClientCreator(DownloadParameters parameters) {
        this.parameters = parameters;
    }

    /** Erzeugt den passenden Http-Client. */
    public CloseableHttpClient createClosableHttpClient() {
        log("Start");
        HttpClientBuilder builder = HttpClients.custom();

        addRedirectHandling(builder);

        addProxyUsing(builder);
        builder.setUserAgent(USER_AGENT);

        CloseableHttpClient httpClient = builder.build();
        log("httpClient created");
        return httpClient;
    }

    private void addRedirectHandling(HttpClientBuilder builder) {
        RedirectHandling redirectHandling = parameters.getRedirectHandling();
        switch (redirectHandling) {
            case STANDARD:
                // Nichts zu tun.
                break;
            case LAX:
                builder.setRedirectStrategy(new LaxRedirectStrategy());
                break;
            case NONE:
                builder.disableRedirectHandling();
                break;
            default:
                throw new RuntimeException("Unknown RedirectHandling " + redirectHandling);
        }
    }

    private void addProxyUsing(HttpClientBuilder builder) {
        if (parameters.useProxy()) {
            log("using proxy");
            Proxy proxy = parameters.getProxy();
            if (parameters.useRotatingProxies()) {
                log("using rotating proxy");
                RotatingProxies rotatingProxies = parameters.getRotatingProxies();
                proxy = rotatingProxies.getProxy();
            }
            log("use proxy " + proxy);
            HttpHost httpHost = new HttpHost(proxy.getAddress(), proxy.getPort());
            DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(httpHost);
            builder.setRoutePlanner(routePlanner);
        }
    }

    /** Loggt die übergebene Nachricht. */
    private void log(String message) {
        if (parameters.weHaveALogger()) {
            Logger logger = parameters.getLogger();
            logger.log(message, 1);
        }
    }

}
