/*
 * Scone - The Web Enhancement Framework
 * Copyright (C) 2009 Harald Weinreich, Volkert Buchmann, Frank Wollenweber, Torsten Haß
 *
 * This program 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 2
 * of the License, or (at your option) any later version.
 * 
 * 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package scone.proxy;


import java.io.IOException;
import java.util.StringTokenizer;

import com.ibm.wbi.RequestEvent;
import com.ibm.wbi.RequestRejectedException;
import com.ibm.wbi.markuplanguage.html.HtmlEditor;
import com.ibm.wbi.markuplanguage.html.HtmlItem;
import com.ibm.wbi.markuplanguage.html.HtmlTag;
import com.ibm.wbi.protocol.http.DocumentInfo;
import com.ibm.wbi.protocol.http.HttpEditor;
import com.ibm.wbi.protocol.http.HttpResponse;


public class NewServerResponseEditor extends HttpEditor {
    // Change Server name from:
    private String newServer = null;
    private String newPort = null;

    // to this:
    private String oldServer = null;
    private String oldPort = null;

    public NewServerResponseEditor(String oldServer, String newServer) {
        this.oldServer = oldServer;
        this.newServer = newServer;
    }

    public NewServerResponseEditor(String oldServer, int oldPort, String newServer, int newPort) {
        this(oldServer, newServer);
        this.oldPort = Integer.toString(oldPort);
        this.newPort = Integer.toString(newPort);
    }

    public void handleRequest(RequestEvent requestevent)
            throws RequestRejectedException, IOException {
 
        DocumentInfo documentinfo = (DocumentInfo) requestevent.getRequestInfo();

        if (!documentinfo.getResponseContentType().equals("text/html")) {
            throw new RequestRejectedException();
        }
        HttpResponse httpresponse = new HttpResponse(documentinfo.getResponseHeader());

        // Remove content length
        httpresponse.removeContentLength();
        documentinfo.setResponseHeader(httpresponse.produceResponseWithoutContent());

        boolean header = false;
        boolean base = false;
        // Edit document with WBIs fucking HtmlEditor...
        HtmlEditor htmleditor = new HtmlEditor(requestevent.getMegInputStream(), requestevent.getMegOutputStream());

        do {
            HtmlItem htmlitem = htmleditor.nextToken();

            if (htmlitem == null) {
                break;
            }      // That's it...
            if (htmlitem instanceof HtmlTag) {
                HtmlTag htmltag = (HtmlTag) htmlitem;
                String tag = htmltag.getId();

                // Start header...
                if (tag.equals("head")) {
                    header = true;
                    htmleditor.write(htmltag);
                    continue;
                }
                // Header ends: write base if necessary...
                if (tag.equals("/head")) {
                    header = false;
                    // if(!base)
                    // htmleditor.write("<BASE HREF='" + getBase() + "'>\n");
                    htmleditor.write(htmltag);
                    continue;
                }
                // first base in header found
                if (header && !base && tag.equals("base")) {
                    String s1 = htmltag.getAttribute("href");

                    if (s1 != null) {
                        base = true;
                        // setBase(s1);
                        htmleditor.write(htmltag);
                    }
                    continue;
                }
                // rewrite image, frame etc. tags
                if (tag.equals("img") || tag.equals("frame")) {
                    String s2 = rewriteSource(htmltag.getAttribute("src"));

                    if (s2 != null) {
                        htmltag.setAttribute("src", s2);
                    }
                    htmleditor.write(htmltag);
                    continue;
                }
                // background images
                if (tag.equals("body") || tag.equals("td") || tag.equals("tr")
                        || tag.equals("th") || tag.equals("table")) {
                    String s3 = rewriteSource(htmltag.getAttribute("background"));

                    if (s3 != null) {
                        htmltag.setAttribute("background", s3);
                    }
                    htmleditor.write(htmltag);
                    continue;
                }
                // Links
                if (tag.equals("a") || tag.equals("area") || tag.equals("link")) {
                    String s4 = rewriteSource(htmltag.getAttribute("href"));

                    if (s4 != null) {
                        htmltag.setAttribute("href", s4);
                    }
                    htmleditor.write(htmltag);
                    continue;
                }
                // form action tag...
                if (tag.equals("form")) {
                    String s6 = rewriteLink(htmltag.getAttribute("action"));

                    if (s6 != null) {
                        htmltag.setAttribute("action", s6);
                    }
                    htmleditor.write(htmltag);
                    continue;
                }
                // meta tags...
                if (tag.equals("meta")) {
                    String s7 = htmltag.getAttribute("content");

                    if (s7 == null) {
                        htmleditor.write(htmltag);
                    } else {
                        StringTokenizer stringtokenizer = new StringTokenizer(s7, ";");
                        StringBuffer stringbuffer = new StringBuffer();

                        while (stringtokenizer.hasMoreElements()) {
                            String s11 = stringtokenizer.nextToken().trim();

                            if (s11.length() > 3
                                    && s11.substring(0, 3).equals("url")) {
                                stringbuffer.append("URL=" + rewriteLink(s11.substring(4)) + "; ");
                            } else {
                                stringbuffer.append(s11 + "; ");
                            }
                        }
                        htmltag.setAttribute("content", stringbuffer.toString());
                        htmleditor.write(htmltag);
                    }
                    continue;
                }
                // option            
                if (tag.equals("option")) {
                    String s9 = htmltag.getAttribute("value");

                    if (s9 != null && s9.startsWith("http://")) {
                        htmltag.setAttribute("value", rewriteLink(s9));
                    }
                    htmleditor.write(htmltag);
                    continue;
                }
            }
            htmleditor.writeLastToken();
        } while (true);
    }
   
    /* public void setBase(String base) 
     {
     initBase(base);
     }

     public void setServer(String server) 
     {
     this.server=server;
     base = protocol+server+path;
     }
     public String getBase() 
     {
     return base;
     }
     */

    // Modifies a link URL (href=)
    public String rewriteLink(String link) {
        if (link == null) {
            return null;
        }

        if (link.startsWith("http://"))  // a server is given, so the URL should be changed...
        {
            String protocol = "http://";
            String rest = link.substring(7);

            System.out.println(rest);
            int serverlen = rest.indexOf("/");
            String server = rest.substring(0, serverlen);

            rest = link.substring(serverlen);
            if (oldPort == null) {   // No port...
                if (server.equals(oldServer)) {
                    link = protocol + this.newServer + rest;
                } else   // with port...
                if (server.equals(oldServer)
                        || server.equals(oldServer + ":" + oldPort)) {
                    link = protocol + this.newServer + this.newPort + rest;
                }
            }
        }

        /* int i = link.indexOf(":");    // Is there a colon?
         int j = link.indexOf("/");    // Where is the first slash?
         if(i == -1 || j != -1 && i >= j)  // No protocol OR no (server and path) OR Colon after Slash !?! (Query?)
         if(link.startsWith("/"))       // absolute URL?
         link = protocol + server + link;
         else
         link = base + link;  // base = protocol + server + path
         */
        return link; 
    }

    // Modifies a source URL (src=)
    public String rewriteSource(String source) {
        return rewriteLink(source);
    }

}
