# -*- 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 several classes that help to consolidate the various 
#  variables related to an HTTP request.

from Library.Base.Classwork import AnObject
from Library.Base.Interfaces import IsPrintable 
from Library.String.PyStrings import String
import os, time

## The format used to create a string representation of HTTPRequestRemoteInfo
hrriStringRepresentation = "{user}@{host}:{port} [{addr}:{port}]"

## The format used to create a string represenation of HTTPRequestRequestInfo
hrqiStringRepresentation = "{method} {uri} HTTP/1.1\n"

## The format used to create a string representation of HTTPRequestServerInfo
hrsiStringRepresentation = ("\"{software}\" running on {name}:{port} "
                            "[{address}:{port}] using {protocol}")
                            
## The default content type
hrciDefaultType = "text/html"
## The default request method
hrqiDefaultMethod = "GET"
## The default request URI
hrqiDefaultPath = "/"

## This class consolidates content information for an HTTP request.
class HTTPRequestContentInfo(AnObject, IsPrintable):
    ## Constructor
    def __init__(Self):
        AnObject.__init__(Self)
    
    ## Initializer    
    def init(Self):        
        Self.length = 0
        Self.contentType = hrciDefaultType
        
        return AnObject.init(Self)
        
    ## Get the content information from the environment.  This routine
    #  assumes that the script is being run as part of a CGI environment.
    def get(Self):
        Self.length = int(os.getenv('CONTENT_LENGTH', 0))
        Self.contentType = os.getenv('CONTENT_TYPE', "")
        
    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the content information.  This
    #  string is suitable for inclusion in a set of HTTP headers sent as part
    #  of an HTTP request.
    def toString(Self):
        result = "Content-length: " + str(Self.length) + "\n"
        result = result + "Content-type: " + Self.contentType + "\n"
        
        return result
        
## This class consolidates date information as part of an HTTP request.
class HTTPRequestDateInfo(AnObject, IsPrintable):
    ## Constructor
    def __init__(Self):
        AnObject.__init__(Self)
    
    ## Initializer    
        Self.gmt = time.gmtime()
        Self.local = time.localtime()
        
        return AnObject.init(Self)
        
    ## Get the date information from the environment.  This routine assumes
    #  that the script is being run as part of a CGI environment. 
    def get(Self):
        Self.gmt = time.strptime(os.getenv('DATE_GMT',
          timeLocalStringRepresentation), time.gmtime())
        Self.local = time.strptime(os.getenv('DATE_LOCAL',
          timeLocalStringRepresentation), time.localtime())
          
    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the date information.  This
    #  string is suitable for inclusion in a set of HTTP headers sent as part
    #  of an HTTP request.
    def toString(Self):
        result = "Date: " + String.fromGMTimeAsRFC2822(Self.gmt)
        result = result + "\n"
        
        return result
        
## This class consolidates document information for an HTTP request.
class HTTPRequestDocumentInfo(AnObject):
    ## Constructor
    def __init__(Self):
        AnObject.__init__(Self)
        
    ## Initializer        
    def init(Self):
        Self.name = ""
        Self.root = ""
        Self.URI = ""
        
        return AnObject.init(Self)
        
    ## Get the attributes of the class from the environment.  This routine
    #  assumes that the script is being run under a CGI environment.
    def get(Self):
        Self.name = os.getenv('DOCUMENT_NAME', "")
        Self.root = os.getenv('DOCUMENT_ROOT', "")
        Self.URI = os.getenv('DOCUMENT_URI', "")
        
    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the document information.  This
    #  string contains the document URI. 
    def toString(Self):
        return Self.URI

## This class consolidates path information for an HTTP request.
class HTTPRequestPathInfo(AnObject):
    ## Constructor
    def __init__(Self):
        AnObject.__init__(Self)
    
    ## Initializer    
    def init(Self):
        Self.value = ""
        Self.info = ""
        Self.ext = ""
        Self.translated = ""
        
        return AnObject.init(Self)
        
    ## Get the attributes of the class from the environment.  This routine
    #  assumes that the script is being run under a CGI environment.
    def get(Self):
        Self.value = os.getenv('PATH', "")
        Self.info = os.getenv('PATH_INFO', "")
        Self.ext = os.getenv('PATH_EXT', "")
        Self.translated = os.getenv('PATH_TRANSLATED', "")
        
    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the path information.  This
    #  string contains the path value.
    def toString(Self):
        return Self.value

## This class consolidates remote information for an HTTP request.
class HTTPRequestRemoteInfo(AnObject):
    ## Constructor
    def __init__(Self):
        AnObject.__init__(Self)
        
    ## Initializer        
    def init(Self):
        Self.address = ""
        Self.host = ""
        Self.port = 0
        Self.ident = ""
        Self.user = ""
        
        return AnObject.init(Self)
        
    ## Get the attributes of the class from the environment.  This routine
    #  assumes that the script is being run under a CGI environment.
    def get(Self):
        Self.address = os.getenv('REMOTE_ADDR', "")
        Self.host = os.getenv('REMOTE_HOST', "")
        Self.port = int(os.getenv('REMOTE_PORT', 0))
        Self.ident = os.getenv('REMOTE_IDENT', "")
        Self.user = os.getenv('REMOTE_USER', "")
        
    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the content information.  This
    #  string is formatted according to the manner specified by
    #  #hrriStringRepresentation.
    def toString(Self):
        return hrriStringRepresentation.format(user=Self.user,
          host=Self.host, port=Self.port, addr=Self.address)

## This class consolidates request information for an HTTP request.
class HTTPRequestRequestInfo(AnObject):
    ## Constructor
    def __init__(Self):
        AnObject.__init__(Self)
    
    ## Initializer    
    def init(Self):
        Self.method = hrqiDefaultMethod
        Self.uri = hrqiDefaultPath
        
        return AnObject.init(Self)
        
    ## Get the attributes of the class from the environment.  This routine
    #  assumes that the script is being run under a CGI environment. 
    def get(Self):
        Self.method = os.getenv('REQUEST_METHOD', "")
        Self.uri = os.getenv('REQUEST_URI', "")
        
    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the request information.  This
    #  string is formatted according to the manner specified by
    #  hrqiStringRepresentation.
    def toString(Self):
        return hrqiStringRepresentation.format(method=Self.method.upper(),
          uri=Self.uri)

## This class consolidates request information for an HTTP request.
class HTTPRequestScriptInfo(AnObject):
    ## Constructor  
    def __init__(Self):
        AnObject.__init__(Self)
    
    ## Initializer    
    def init(Self):
        Self.fileName = ""
        Self.scriptName = ""
        
        return AnObject.init(Self)

    ## Get the attributes of the class from the environment.  This routine
    #  assumes that the script is being run under a CGI environment.
    def get(Self):
        Self.fileName = os.getenv('SCRIPT_FILENAME', "")
        Self.name = os.getenv('SCRIPT_NAME', "")
        
    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the request information.  This
    #  string is simply the name of the script. 
    def toString(Self):
        return Self.scriptName

## This class consolidates server information for an HTTP request.
class HTTPRequestServerInfo(AnObject):
    ## Constructor    
    def __init__(Self):
        AnObject.__init__(Self)
        
    ## Initializer
    def init(Self):
        Self.name = ""
        Self.address = ""
        Self.admin = ""
        Self.port = 0
        Self.protocol = ""
        Self.root = ""
        Self.software = ""
        Self.signature = ""
        
        return AnObject.init(Self)
        
    ## Get the attributes of the class from the environment.  This routine
    #  assumes that the script is being run under a CGI environment.
    def get(Self):
        Self.name = os.getenv('SERVER_NAME', "")
        Self.address = os.getenv('SERVER_ADDR', "")
        Self.admin = os.getenv('SERVER_ADMIN', "")
        Self.port = int(os.getenv('SERVER_PORT', 0))
        Self.protocol = os.getenv('SERVER_PROTOCOL', "")
        Self.root = os.getenv('SERVER_ROOT', "")
        Self.software = os.getenv('SERVER_SOFTWARE', "")
        Self.signature = os.getenv('SERVER_SIGNATURE', "")
        
    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the content information.  This
    #  string is formatted according to the manner specified by
    #  #hrsiStringRepresentation.
    def toString(Self):
        return hrsiStringRepresentation.format(software=Self.software,
          name=Self.name, addr=Self.address, protocol=Self.protoocol)

## This class consolidates HTTP information for an HTTP request. 
class HTTPRequestHTTPInfo(AnObject):
    ## Constructor   
    def __init__(Self):
        AnObject.__init__(Self)
        
    ## Initializer
    def init(Self):
        Self.accept = {}
        Self.accept["contentType"] = ""
        Self.accept["charset"] = ""
        Self.accept["encoding"] = ""
        Self.accept["language"] = ""
        Self.cacheControl = ""
        Self.connection = ""
        Self.cookie = ""
        Self.host = ""
        Self.userAgent = ""
        
        return AnObject.init(Self)
        
    ## Get the attributes of the class from the environment.  This routine
    #  assumes that the script is being run under a CGI environment.
    def get(Self):
        Self.accept["contentType"] = os.getenv('HTTP_ACCEPT', "")
        Self.accept["charset"] = os.getenv('HTTP_ACCEPT_CHARSET', "")
        Self.accept["encoding"] = os.getenv('HTTP_ACCEPT_ENCODING', "")
        Self.accept["language"] = os.getenv('HTTP_ACCEPT_LANGUAGE', "")
        Self.cacheControl = os.getenv('HTTP_CACHE_CONTROL', "")
        Self.connection = os.getenv('HTTP_CONNECTION', "")
        Self.cookie = os.getenv('HTTP_COOKIE', "")
        Self.host = os.getenv('HTTP_HOST', "")
        Self.userAgent = os.getenv('HTTP_USER_AGENT', "")

    # IsPrintable implementation -----------------------------------------------
    ## Construct a string representation of the HTTP information.  This
    #  representation is suitable for inclusion in a list of HTTP headers being
    #  sent as part of a request.
    def toString(Self):
        result = "Accept: " + Self.accept["contentType"] + "\n"
        result = result + "Accept-Charset: " + Self.accept["charset"] + "\n"
        result = result + "Accept-Encoding: " + Self.accept["encoding"] + "\n"
        result = result + "Accept-Language: " + Self.accept["language"] + "\n"
        
        result = result + "Cache-Control: " + Self.cacheControl + "\n"
        result = result + "Connection: " + Self.connection + "\n"
        result = result + "User-Agent: " + Self.userAgent + "\n"
        if len(Self.cookie) > 0:
            result = result + "Set-Cookie: " + Self.cookie + "\n"
        
        return result
