package com.mindprod.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;

/**
 * simulates a browser posting a form to CGI via GET. See com.mindprod.submitter for sample code to use this class.
 *
 * @author Roedy Green, Canadian Mind Products may be copied and used freely for any purpose but military.
 * @version 1.8 2008-07-27 handle case where URL given was not HTTP.
 */
public final class Get extends Http
    {
    // -------------------------- PUBLIC INSTANCE  METHODS --------------------------
    /**
     * constructor
     */
    public Get()
        {
        }

    /**
     * Send a form full of data to the CGI host using GET.
     *
     * @param url      complete URL including get parms. Use Request.appendCGIPair to build up parms on the tail end.
     *                 only http:
     * @param encoding encoding of the byte stream result, usually UTF-8 or or ISO-8859-1.
     * @return CGI host's response with headers and embedded length fields stripped.
     */
    @SuppressWarnings( { "UnusedAssignment", "MethodNamesDifferingOnlyByCase", "WeakerAccess" } )
    public String get( URL url, String encoding )
        {
        try
            {
            // defaults
            responseCode = DEFAULT_RESPONSE_CODE;
            responseMessage = DEFAULT_RESPONSE_MESSAGE;

            // O P E N

            final HttpURLConnection urlc = ( HttpURLConnection ) url.openConnection();
            urlc.setAllowUserInteraction( false );
            urlc.setDoInput( true );
            urlc.setDoOutput( false );// nothing beyond original request
            urlc.setUseCaches( false );
            urlc.setRequestMethod( "GET" );
            setStandardProperties( urlc );

            urlc.connect();
            /* save responseCode for later retrieval */
            responseCode = urlc.getResponseCode();
            responseMessage = urlc.getResponseMessage();
            // get size of message. -1 means comes in an indeterminate number of chunks.
            int estimatedLength = urlc.getContentLength();
            if ( estimatedLength < 0 )
                {
                // quite common for no length field
                estimatedLength = 32 * 1024;
                }
            final InputStream is = urlc.getInputStream();

            // content encoding might be null
            final boolean gzipped = "gzip".equals( urlc.getContentEncoding() );

            // R E A D
            String result =
                    Read.readStringBlocking( is,
                            estimatedLength,
                            readTimeout,
                            gzipped,
                            encoding );

            // C L O S E
            is.close();
            urlc.disconnect();

            return result;
            }
        catch ( ClassCastException e )
            {
            // was not an http: url
            return null;
            }
        catch ( IOException e )
            {
            return null;
            }
        }// end get

    /**
     * Send a form full of data to the CGI host using GET.
     *
     * @param host     host name of the website, Should be form:"www.mindprod.com", no lead http://.
     * @param port     -1 if default, 8081 for local echoserver.
     * @param encoding encoding of the byte stream result, usually UTF-8 or or ISO-8859-1.
     * @param action   action of form, page on website. Usually has a lead / and no trailing /.
     * @param parms    alternating parm value without = or ? not urlEncoded.
     * @return CGI host's response with headers and embedded length fields stripped.
     */
    @SuppressWarnings( { "UnusedAssignment", "MethodNamesDifferingOnlyByCase" } )
    public String get( String host,
                       int port,
                       String encoding,
                       String action,
                       String... parms )
        {
        try
            {
            // defaults
            responseCode = DEFAULT_RESPONSE_CODE;
            responseMessage = DEFAULT_RESPONSE_MESSAGE;

            // O P E N
            final StringBuilder sb = new StringBuilder( 200 );
            for ( int i = 0; i < parms.length - 1; i += 2 )
                {
                if ( i != 0 )
                    {
                    sb.append( "&" );
                    }
                sb.append( URLEncoder.encode( parms[ i ], "UTF-8"
                        /* encoding */ ) );
                sb.append( '=' );
                sb.append( URLEncoder.encode( parms[ i + 1 ], "UTF-8"
                        /* encoding */ ) );
                }

            final String encodedParms = sb.toString();
            // O P E N

            // URL will encode target and parms.
            URL url = new URI( "http",
                    null,
                    host,
                    port,
                    action,
                    null
                    /* no query here, or would be double encoded */,
                    null ).toURL();
            url = new URL( url.toString() + '?' + encodedParms );

            return get( url, encoding );
            }
        catch ( URISyntaxException e )
            {
            // was not an http: url
            return null;
            }
        catch ( IOException e )
            {
            return null;
            }
        }// end get
    }