"""
= Redirect: Redirection for Trac =

== Purpose and Usage ==

The redirect wiki macro provides redirect functionality for Trac with
backlink support. It takes a qualified [TracLinks TracLink] (type:id)
as argument, e.g. `wiki:SandBox`, `source:README` or
`ticket:123`. Users with a JavaScript-enabled browser will get
redirected to the page specified by this shortlink.

== Installation ==

Put the file `redirect.py` either in the global wiki-macros directory
of your Trac installation (typically `/usr/share/trac/wiki-macros`) or
into the `wiki-macros` subdirectory of your project.

Then add these lines to the `templates/site_header.cs` file within
your project:
{{{
<?cs if:args.redirectedfrom ?>
<?cs set:chrome.nav.metanav.redirectedfrom =
  '<div class="redirect">Redirected from <a href="' +
  trac.href.wiki + '/' + args.redirectedfrom + '?redirect=no">' +
  args.redirectedfrom + '</a>' +
  ' (<a href="' + base_url + HTTP.PathInfo + '">hide</a>)</div>' ?>
<?cs /if ?>
}}}

Additionally, you should add this line
{{{
.redirect { color: #cccccc; }
}}}
to the `templates/site_css.cs` of your project.

== Author and license ==

Copyright 2005, 2006
 * Bernhard Haumacher (haui at haumacher.de)
 * Thomas Moschny (moschny at ipd.uni-karlsruhe.de)

{{{
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
}}}

== Additional information ==

Please visit: http://svn.ipd.uka.de/trac/javaparty/wiki/TracRedirect.
"""

import re
from StringIO import StringIO
from trac.wiki.formatter import Formatter
from trac.wiki.api import WikiSystem

class MyFormatter(Formatter):

    def format(self, text):
        self.formatted_link = None
        self.missing = False
        class NullOut(object):
            def write(self, data): pass
        Formatter.format(self, text, NullOut())
        return self.formatted_link, self.missing

    def _shref_formatter(self, match, fullmatch):
        if not self.formatted_link:
            namespace = fullmatch.group('sns')
            target    = fullmatch.group('stgt')
            if target[0] in "'\"":
                target = target[1:-1]
            if namespace == 'wiki':
                wiki = WikiSystem(self.env)
                if not wiki.has_page(target):
                    self.missing = True
            self.formatted_link = self._make_link(namespace, target, match, match)
        return

def execute(hdf, args, env):
    curpage = hdf.getValue('wiki.page_name', "")
    if not curpage:
        curpage = 'WikiStart'

    preview = hdf.getValue('args.preview', "")
    shouldRedirect = (hdf.getValue('args.redirect', "yes") == "yes") and (not preview)

    db = env.get_db_cnx()
    out = StringIO()
    link, missing = MyFormatter(env, True, db).format(args)

    if link and not missing:
        out.write('<div class="system-message">')
        out.write('<strong>Redirect: </strong>')
        out.write('This page redirects to %s ' % link)
        out.write('</div>')

        if shouldRedirect:
            link_target = re.sub(r'^.*href="([^"]*)".*$', r'\1', link)

            out.write('<form id="redirect" method="GET" action="%s">' % link_target)
            out.write('<input type="hidden" name="redirectedfrom" value="%s">' % curpage)
            out.write('</form>')

            out.write('\n')
            out.write('<script language="JavaScript">\n')
            out.write('document.forms["redirect"].submit();\n')
            out.write('</script>\n')

    elif link and missing:
        # Internal link to a non-existing page
        out.write('<div class="system-message">')
        out.write('<strong>Redirection Error: </strong>')
        out.write('Redirection target not found: %s' % link)
        out.write('</div>')

    else:
        # No arguments given to the redirect macro
        out.write('<div class="system-message">')
        out.write('<strong>Redirection Error: </strong>')
        out.write('Missing redirection target.')
        out.write('</div>')

    return out.getvalue()

