// AppRequest.java

/**
*    Copyright (C) 2008 10gen Inc.
*  
*    This program is free software: you can redistribute it and/or  modify
*    it under the terms of the GNU Affero General Public License, version 3,
*    as published by the Free Software Foundation.
*  
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU Affero General Public License for more details.
*  
*    You should have received a copy of the GNU Affero General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package ed.appserver;

import java.io.*;

import ed.js.*;
import ed.js.engine.*;
import ed.net.httpserver.*;
import ed.log.*;

public class AppRequest {
    
    AppRequest( AppContext context , HttpRequest request , String uri ){
        _context = context;
        _request = request;

        if ( uri == null )
            uri = _request.getURI();
        
        _uri = uri.equals( "/" ) ? "/index" : uri;
    }

    void setResponse( HttpResponse response ){
	getScope().put( "response" , response , true );
    }

    public AppContext getContext(){
        return _context;
    }

    public Scope getScope(){
        
        if ( _scope == null ){
            _scope = _context.scopeChild();

            _scope.put( "request" , _request , true );
            _scope.lock( "request" );

            _scope.put( "head" , _head , true );
            _scope.lock( "head" );
            
            _scope.put( "session" , Session.get( _request.getCookie( Session.COOKIE_NAME ) , _context.getDB() ) , true );
            _scope.lock( "session" );
            
            _context.getScope().setTLPreferred( _scope );
        }
        
        return _scope;
    }

    public String getURI(){
        return _uri;
    }

    String getRoot(){
        return _context.getRoot();
    }

    String getCustomer(){
        return "";
    }

    boolean isStatic(){
        String uri = getWantedURI();
        
        if ( uri.endsWith( ".jxp" ) )
            return false;
        
        int period = uri.indexOf( "." );
        if ( period < 0 )
            return false;

        String ext = uri.substring( period + 1 );
        if ( MimeTypes.get( ext.toLowerCase() ) == null )
            return false;

        return true;
    }

    private String getOverrideURI(){
        String foo = getOverrideURI( "mapUrlToJxpFileCore" );
        if ( foo != null )
            return foo;

        foo = getOverrideURI( "mapUrlToJxpFile" );
        if ( foo != null )
            return foo;
        
        return null;
    }
    
    private String getOverrideURI( String funcName ){
        Object o = getScope().get( funcName );
        if ( o == null )
            return null;
        
        if ( ! ( o instanceof JSFunction ) )
            return null;
        
        Object res = ((JSFunction)o).call( getScope() , new JSString( getURI() ) , _request , getScope().get( "response" ) );
        if ( res == null )
            return null;
        return res.toString();
    }
    
    private String getWantedURI(){
        if ( _wantedURI != null )
            return _wantedURI;
        
        String override = getOverrideURI();
        if ( override != null )
            _wantedURI = override;
        else
            _wantedURI = getURI();
        
        _wantedURI = _wantedURI.replaceAll( "//+" , "/" );

        return _wantedURI;
    }
    

    File getFile()
        throws FileNotFoundException {
        return _context.getFile( getWantedURI() );
    }

    public JSArray getHead(){
        return _head;
    }

    public JSArray getHeadToPrint(){
        _head.lock();
        return _head;
    }

    public Logger getLogger(){
        return _context._logger;
    }

    void done( HttpResponse response ){
        _context.getScope().setTLPreferred( null );
        Session session = (Session)_scope.get( "session" );
        if ( session.sync( _context.getDB() ) )
            response.addCookie( Session.COOKIE_NAME , session.getCookie() );
    }
    
    void makeThreadLocal(){
        _tl.set( this );
    }

    void unmakeThreadLocal(){
        _tl.set( null );
    }

    public static AppRequest getThreadLocal(){
        return _tl.get();
    }

    final String _uri;
    final HttpRequest _request;
    final AppContext _context;
    final JSArray _head = new HeadArray();

    private Scope _scope;
    
    String _wantedURI = null;

    static ThreadLocal<AppRequest> _tl = new ThreadLocal<AppRequest>();
}

@@ -810,16 +810,43 @@
 d.log.*;
+%0Aimport ed.appserver.jxp.*;
 %0A%0Apublic
@@ -3914,32 +3914,267 @@
 _logger;%0A    %7D%0A%0A
+    public void print( String s )%7B%0A        Object o = _scope.get( %22print%22 );%0A        if ( ! ( o instanceof JxpServlet.MyWriter ) )%0A            System.out.print( s );%0A        else%0A            ((JxpServlet.MyWriter)o).print( s );%0A    %7D%0A%0A
     void done( H

print method which defers to the print stream