# -*- coding: UTF-8 -*-
#    This file is part of arena.
#   
#    arena is free software: you can redistribute it and/or modify it
#    under the terms of the GNU General Public License as published by the
#    Free Software Foundation; either version 3 of the License or, at your
#    option, any later version.
#
#    arena is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABLITY
#    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
#    License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with arena.  If not, see <http://www.gnu.org/licenses/>.

## @file
#  This file defines a stream class that can be used to buffer output from a
#  CGI script.  This allows an entire response document to be constructed
#  (including certain HTTP headers, such as cookies) before the data is returned
#  to the client.

from Library.IO.StringStreams import AStringStream
import Cookie

## The default content type used by the buffer
hrbDefaultContentType = "text/html"

## This class can be used to buffer output from a CGI script.
#    
#  It provides a few public attributes to make HTTP responses easy:
#      - headers        A dictionary of HTTP response headers that are written
#                       before the actual content of the response.
#      - Cookie         A dictionary of cookie values that are included as 
#                       part of the HTTP response headers.
class AnHTTPResponseBuffer(AStringStream):
    
    ## Construct a new buffered output instance.
    def __init__(Self, *values):        
        AStringStream.__init__(Self, values)
    
    ## Initialize a new HTTP response buffer.
    #    
    #  The attributes of the instance are filled with their default values.
    def init(Self):
        result = AStringStream.init(Self)
        
        if result == True:
            Self.Cookie = Cookie.SimpleCookie()
            Self.headers = {
              "Content-type": hrbDefaultContentType,
              "Content-length": 0
            }

        return result
        
    ## Destroy the HTTP response buffer.    
    def __del__(Self):        
        # Python reference counting makes this unreliable to call from here
        # print Self.toString()
        del Self.Cookie
        del Self.headers
        AStringStream.__del__(Self)
        
    # IsPrintable implementation -----------------------------------------------
    ## Return a string representation of the buffer.
    #
    #  The string is formatted for presentation to an HTTP client. This means
    #  that it will first include the necessary HTTP headers, followed by a
    #  blank line and then the contents of the document itself.  
    def toString(Self):        
        output = ""
        
        # Include the content length as part of the headers
        contentLength = Self.length
        Self.headers["Content-length"] = contentLength
                   
        # Write the headers
        for key, value in Self.headers.iteritems():
            output += key + ": " + str(value) + "\n"
            
        # Write the cookies
        if len(Self.Cookie) > 0:
            output += Self.Cookie.output() + "\n"
        
        # Separate the headers from the content by a blank line    
        output += "\n"
        
        # Write the content
        if contentLength > 0:
            output += Self._Handle.getvalue()
        
        return output
