package BAST;

use strict;
use Catalyst qw/-Debug Static/;
use XML::LibXML;
use XML::LibXSLT;

use BAST::Frame;

our $VERSION = '0.01';

BAST->config(
    name => 'BAST',
    root => '/home/matthewt/tests/BAST/root',
);

BAST->setup;

__PACKAGE__->mk_accessors(qw/parent caller current/);

sub chain_ctx {
  my ($outer, $axis, $in_frame, $out_frame) = @_;
  my $inner = bless({ %{$outer} }, ref $outer);
  $inner->req($in_frame);
  $inner->res($out_frame);
  $inner->$axis($outer);
  $inner->prepare_action;
  return $inner;
}

{
  my $i = 0; # Lexical capture for gensyms
  sub register_uri_handler {
    my ($c, $uri, $sub) = @_;
    $c->set_action('gensym'.$i++, $sub, 'BAST::C::Runtime', [ "Path('${uri}')" ]);
  }

}

sub uri_redispatch {
  my ($c, $req, $res) = @_;
  my $newreq = BAST::Frame->create(join('/',@{$req->args}), $req->body);
  $c->chain_ctx('caller', $newreq, $res)->dispatch;
  return $res;
}

sub primitive_execute {
  my ($c, $trans) = @_;
  my $root = $trans->document->getDocumentElement;
  unless ($root->nodeName eq 'primitive-prov') {
    die "Couldn't handle ".$c->req->path;
  }
  my $tag_handler;
  $tag_handler = sub {
    my ($node, $c, $axis, $r) = @_;
    my $frame = BAST::Frame->create($node->getAttribute("trans"));
    my $inner = $c->chain_ctx($axis, $frame, $r);
    foreach my $child ($node->findnodes('primitive-prov')) {
      $tag_handler->($child, $inner, 'parent', $inner->req);
    }
    $inner->current($node);
    $inner->dispatch;
  };
  $tag_handler->($root, $c, 'caller', $c->res);
}

1;
