#!/usr/bin/perl -w

# ---------------------------------------------------------------------------

# set this to the directory under which WebMake can edit files.
# $FILE_BASE = '/home/jm/public_html';
$FILE_BASE = '/home/jm/ftp/wmtest';

# The name of the WebMake file to use.
$WMKFILE = 'main.wmk';

# set this, if WebMake is not installed in the std locations.
$WEBMAKE = '/home/jm/ftp/webmake';

# ---------------------------------------------------------------------------

if (defined $WEBMAKE) {
  push (@INC, "$WEBMAKE/lib"); push (@INC, "$WEBMAKE/site_perl");
}
if (defined $CVSROOT) { $ENV{'CVSROOT'} = $CVSROOT; }

use CGI qw(-private_tempfiles);
use CGI::Carp 'fatalsToBrowser';
$CGI::POST_MAX = 1024*1024;

my $q = new CGI();

require HTML::WebMake::Main;

if ($q->cgi_error()) {
  print header(-status=>cgi_error()); exit;
}

my $myurl = $q->url(-query=>1);

# replace __HOST__ with the URL's hostname in FILE_BASE if present.
# This allows multiple sites to be edited with only one script, as
# long as they all ScriptAlias the same directory.
if ($FILE_BASE =~ /__HOST__/) {
  if ($myurl !~ m,^[a-zA-Z0-9]+://([^/]+)/,) {
    die "no hostname in URL";
  }

  my $host = $1; $host =~ s/:\d+$//;
  $FILE_BASE =~ s/__HOST__/${host}/g;
}

# Some trickery.  Since the WebMake path-canonicalisation code can't work with
# http://.../wmview.cgi?p=... URLs (and nor should it, because they're not
# valid filesystem paths), we use a magic string ("!!WMVIEWCGI!!") as the base
# href for all URLs, then replace that in the output with the correct URL for
# the cgi script.

# First trim off the p=... parameter from myurl and canonicalise it
$myurl =~ s/(&|\?)p=([^&]*)/$1/gs;
$path = $2;
$path =~ s,\%2F,/,gi;		# convert %2F to /
$path =~ s,(?:/+|^)[^/]+$,,g;	# get the dirname
$path = HTML::WebMake::Main::canon_path ($path);
$path =~ s,^/,,g;		# trim leading /

$myurl .= '&p='; $myurl =~ s/\?\&/\?/g;
# later we will subst !!WMVIEWCGI!!/ with $myurl

chdir ($FILE_BASE);

my $f = new HTML::WebMake::Main ({
  'risky_fast_rebuild'	=> 1,
  'verbose'		=> 0,
  'base_href'		=> '!!WMVIEWCGI!!/'.$path
});

$f->setcachefile ("/tmp/webmake_cache/%u/%F");

# set variables for each of the CGI parameters; also set a flag
# variable to indicate that CGI is in use.
my @parms = $q->param();
$f->set_unmapped_content ("CGI.IN_USE", "1");
foreach my $parm (@parms) {
  next if ($parm eq 'p');
  $f->set_unmapped_content ("CGI.$parm", $q->param($parm));
}

# figure out which 'file' to build
my $path = $q->param ('p');
$path ||= $q->path_info();
$path ||= '';

# make it safe for file/shell use (paranoia!)
$path =~ s,[^-_\/A-ZA-z0-9\.\:\\\,\+],_,g;
$path = HTML::WebMake::Main::canon_path ($path);
$path =~ s,^/,,g;		# trim leading /

# if the path ends in a /, emulate a web server by appending
# 'index.html' to the path
if ($path =~ /(?:^|\/)$/) { $path .= 'index.html'; }

# set it as the CGI filename request (before reading .wmk!)
$f->set_unmapped_content ("CGI.RequestURL", $path);

# Read the WebMake file...
$f->readfile ($WMKFILE);

# get the path again; it may have been modified by perl
# code while reading the .wmk.
$path = $f->get_content ("CGI.RequestURL");

# if it's a registered output, then we can build it
if ($f->can_build ($path)) {
  $_ = $f->make_to_string ($path);
  $f->finish();
  s/!!WMVIEWCGI!!/${myurl}/gs;
  print $q->header(), $_;
  exit;
}

# Otherwise, redirect to the live site and let the web server handle it.
# We need to do this for (e.g.) media items etc.; if we were to try
# to handle it, we'd effectively *be* the web server!
my $href = $f->{locations}->{'WebMake.SiteHref'};
if (!defined $href) {
  print $q->header();
  warn "no <site> tag in .wmk, cannot redirect to live site for: $path";
  exit 1;
}

print $q->redirect($href."/".$path);
exit;

