/*
 * Copyright (c) 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;
    }
}
