/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.ejte.ccl.webrunner.proxy;

import java.io.*;

/*
 *
* This class is a wrapper around everything associated with a reply from an HTTP server.This is used by
 *the proxy part of htppd class.
 *
 */
public class HttpResponse
{
        int statusCode;
        String reasonPhrase;
        MimeHeader mh;
        static String CRLF="\r\n";

        /*
         *When a request is sent to HTTP server, it responds with a  status code, which is stored in statusCode,
         *and a textual equivalent,which is stored in reasonPhrase.This single line response is followed by a MIME header.MimeHeader class is used
         *to parse this string.This method is called by constructor of HttpResponse.
         * @author       Deepa Singh(deepa.singh@sun.com)
         *@Company Sun Microsystems Inc.
         @param                request        String request
        */
        public void parse(String request)
        {
                int fsp=request.indexOf(' ');
                int nsp=request.indexOf(' ',fsp+1);
                int eol=request.indexOf('\n');
                String protocol=request.substring(0,fsp);
                statusCode=Integer.parseInt(request.substring(fsp+1,nsp));
                reasonPhrase=request.substring(nsp+1,eol);
                String raw_mime_header=request.substring(eol+1);
                mh=new MimeHeader(raw_mime_header);
        }

        /**
        * Default Constructor.Takes a raw request as parameter and calls parse to create MimeHeader.
        * @author       Deepa Singh(deepa.singh@sun.com)
        *
        */
        HttpResponse(String request)
        {
                parse(request);
        }

        /**
        * Constructor with three parameters
        * @author       Deepa Singh(deepa.singh@sun.com)
        *
        * @param                code        Integer
        * @param                reason         The reason String
        * @param                m                Mimeheader
        */
        HttpResponse(int code,String reason,MimeHeader m)
        {
                statusCode=code;
                reasonPhrase=reason;
                mh=m;
        }

        /**
        *
        * @author       Deepa Singh(deepa.singh@sun.com)
        * @return       String
        */
        public String toString()
        {
                return "HTTP/1.0 "+ statusCode +" " + reasonPhrase + CRLF + mh + CRLF;
    }
}
