/*
 * 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.commons.net.ftp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.Inet6Address;
import java.net.Socket;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.net.util.Base64;

/**
 * Experimental attempt at FTP client that tunnels over an HTTP proxy connection.
 *
 * @since 2.2
 */
public class FTPHTTPClient extends FTPClient {
    private static final byte[] CRLF={'\r', '\n'};
    private final String proxyHost;
    private final int proxyPort;
    private final String proxyUsername;
    private final String proxyPassword;

    private final Charset charset;
    private final Base64 base64 = new Base64();

    private String tunnelHost; // Save the host when setting up a tunnel (needed for EPSV)

    /**
     * Create an instance using the UTF-8 encoding, with no proxy credentials.
     *
     * @param proxyHost the hostname to use
     * @param proxyPort the port to use
     */
    public FTPHTTPClient(final String proxyHost, final int proxyPort) {
        this(proxyHost, proxyPort, null, null);
    }

    /**
     * Create an instance using the specified encoding, with no proxy credentials.
     *
     * @param proxyHost the hostname to use
     * @param proxyPort the port to use
     * @param encoding the encoding to use
     */
    public FTPHTTPClient(final String proxyHost, final int proxyPort, final Charset encoding) {
        this(proxyHost, proxyPort, null, null, encoding);
    }

    /**
     * Create an instance using the UTF-8 encoding
     *
     * @param proxyHost the hostname to use
     * @param proxyPort the port to use
     * @param proxyUser the user name for the proxy
     * @param proxyPass the password for the proxy
     */
    public FTPHTTPClient(final String proxyHost, final int proxyPort, final String proxyUser, final String proxyPass) {
        this(proxyHost, proxyPort, proxyUser, proxyPass, StandardCharsets.UTF_8);
    }


    /**
     * Create an instance with the specified encoding
     *
     * @param proxyHost the hostname to use
     * @param proxyPort the port to use
     * @param proxyUser the user name for the proxy
     * @param proxyPass the password for the proxy
     * @param encoding the encoding to use
     */
    public FTPHTTPClient(final String proxyHost, final int proxyPort, final String proxyUser, final String proxyPass,
            final Charset encoding) {
        this.proxyHost = proxyHost;
        this.proxyPort = proxyPort;
        this.proxyUsername = proxyUser;
        this.proxyPassword = proxyPass;
        this.tunnelHost = null;
        this.charset = encoding;
    }


    /**
     * {@inheritDoc}
     *
     * @throws IllegalStateException if connection mode is not passive
     * @deprecated (3.3) Use {@link FTPClient#_openDataConnection_(FTPCmd, String)} instead
     */
    // Kept to maintain binary compatibility
    // Not strictly necessary, but Clirr complains even though there is a super-impl
    @Override
    @Deprecated
    protected Socket _openDataConnection_(final int command, final String arg)
    throws IOException {
        return super._openDataConnection_(command, arg);
    }

    /**
     * {@inheritDoc}
     *
     * @throws IllegalStateException if connection mode is not passive
     * @since 3.1
     */
    @Override
    protected Socket _openDataConnection_(final String command, final String arg)
    throws IOException {
        //Force local passive mode, active mode not supported by through proxy
        if (getDataConnectionMode() != PASSIVE_LOCAL_DATA_CONNECTION_MODE) {
            throw new IllegalStateException("Only passive connection mode supported");
        }

        final boolean isInet6Address = getRemoteAddress() instanceof Inet6Address;
        String passiveHost = null;

        final boolean attemptEPSV = isUseEPSVwithIPv4() || isInet6Address;
        if (attemptEPSV && epsv() == FTPReply.ENTERING_EPSV_MODE) {
            _parseExtendedPassiveModeReply(_replyLines.get(0));
            passiveHost = this.tunnelHost;
        } else {
            if (isInet6Address) {
                return null; // Must use EPSV for IPV6
            }
            // If EPSV failed on IPV4, revert to PASV
            if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) {
                return null;
            }
            _parsePassiveModeReply(_replyLines.get(0));
            passiveHost = this.getPassiveHost();
        }

        final Socket socket = _socketFactory_.createSocket(proxyHost, proxyPort);
        final InputStream is = socket.getInputStream();
        final OutputStream os = socket.getOutputStream();
        tunnelHandshake(passiveHost, this.getPassivePort(), is, os);
        if (getRestartOffset() > 0 && !restart(getRestartOffset())) {
            socket.close();
            return null;
        }

        if (!FTPReply.isPositivePreliminary(sendCommand(command, arg))) {
            socket.close();
            return null;
        }

        return socket;
    }

    @Override
    public void connect(final String host, final int port) throws SocketException, IOException {

        _socket_ = _socketFactory_.createSocket(proxyHost, proxyPort);
        _input_ = _socket_.getInputStream();
        _output_ = _socket_.getOutputStream();
        final Reader socketIsReader;
        try {
            socketIsReader = tunnelHandshake(host, port, _input_, _output_);
        }
        catch (final Exception e) {
            final IOException ioe = new IOException("Could not connect to " + host + " using port " + port);
            ioe.initCause(e);
            throw ioe;
        }
        super._connectAction_(socketIsReader);
    }

    private BufferedReader tunnelHandshake(final String host, final int port, final InputStream input,
            final OutputStream output) throws IOException, UnsupportedEncodingException {
        final String connectString = "CONNECT " + host + ":" + port + " HTTP/1.1";
        final String hostString = "Host: " + host + ":" + port;

        this.tunnelHost = host;
        output.write(connectString.getBytes(charset));
        output.write(CRLF);
        output.write(hostString.getBytes(charset));
        output.write(CRLF);

        if (proxyUsername != null && proxyPassword != null) {
            final String auth = proxyUsername + ":" + proxyPassword;
            final String header = "Proxy-Authorization: Basic " + base64.encodeToString(auth.getBytes(charset));
            output.write(header.getBytes(charset));
        }
        output.write(CRLF);

        final List<String> response = new ArrayList<>();
        final BufferedReader reader = new BufferedReader(new InputStreamReader(input, getCharset()));

        for (String line = reader.readLine(); line != null && !line.isEmpty(); line = reader.readLine()) {
            response.add(line);
        }

        final int size = response.size();
        if (size == 0) {
            throw new IOException("No response from proxy");
        }

        String code = null;
        final String resp = response.get(0);
        if (resp.startsWith("HTTP/") && resp.length() >= 12) {
            code = resp.substring(9, 12);
        } else {
            throw new IOException("Invalid response from proxy: " + resp);
        }

        if (!"200".equals(code)) {
            final StringBuilder msg = new StringBuilder();
            msg.append("HTTPTunnelConnector: connection failed\r\n");
            msg.append("Response received from the proxy:\r\n");
            for (final String line : response) {
                msg.append(line);
                msg.append("\r\n");
            }
            throw new IOException(msg.toString());
        }
        return reader;
    }
}


