###################################################
# Samba3 NDR server generator for IDL structures
# Copyright jelmer@samba.org 2005
# released under the GNU GPL

package Parse::Pidl::Samba3::Server;

use strict;
use Parse::Pidl::Typelist qw(hasType getType mapType);
use Parse::Pidl::Util qw(has_property ParseExpr);
use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);

my $res = "";
my $tabs = "";

sub indent() { $tabs.="\t"; }
sub deindent() { $tabs = substr($tabs, 1); }
sub pidl($) { $res .= $tabs.(shift)."\n"; }

use vars qw($VERSION);
$VERSION = '0.01';

sub ParseFunction($$)
{
	my ($if,$fn) = @_;

	pidl "/******************************************************************";
	pidl " api_$fn->{NAME}";
	pidl " *****************************************************************/";
	pidl "";
	pidl "static BOOL api_$fn->{NAME}(pipes_struct *p)";
	pidl "{";
	indent;
	pidl uc("$if->{NAME}_q_$fn->{NAME}") . " q_u;";
	pidl uc("$if->{NAME}_r_$fn->{NAME}") . " r_u;";
	pidl "prs_struct *data = &p->in_data.data;";
	pidl "prs_struct *rdata = &p->out_data.rdata;";
	pidl "";
	pidl "if (!$if->{NAME}_io_q_$fn->{NAME}(\"\", &q_u, data, 0))";
	pidl "\treturn False;";
	pidl "";
	if ($fn->{RETURN_TYPE}) {
		pidl "r_u.status = _$fn->{NAME}(p, &q_u, &r_u);";
	} else {
		pidl "_$fn->{NAME}(p, &q_u, &r_u);";
	}
	pidl "";
	pidl "if (!$if->{NAME}_io_r_$fn->{NAME}(\"\", &r_u, rdata, 0))";
	pidl "\treturn False;";
	pidl "";
	pidl "return True;";
	deindent;
	pidl "}";
}

sub ParseInterface($)
{
	my $if = shift;

	ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}});
	
	pidl "";
	pidl "/* Tables */";
	pidl "static struct api_struct api_$if->{NAME}_cmds[] = ";
	pidl "{";
	indent;
	foreach (@{$if->{FUNCTIONS}}) {
		pidl "{\"" . uc($_->{NAME}) . "\", " . uc($_->{NAME}) . ", api_$_->{NAME}},";
	}
	deindent;
	pidl "};";

	pidl "";
	
	pidl "void $if->{NAME}_get_pipe_fns(struct api_struct **fns, int *n_fns)";
	pidl "{";
	indent;
	pidl "*fns = api_$if->{NAME}_cmds;";
	pidl "*n_fns = sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct);";
	deindent;
	pidl "}";

	pidl "";

	pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
	pidl "{";
	indent;
	pidl "return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));";
	deindent;
	pidl "}";
}

sub Parse($$)
{
	my($ndr,$filename) = @_;

	$tabs = "";
	$res = "";

	pidl "/*";
	pidl " * Unix SMB/CIFS implementation.";
	pidl " * server auto-generated by pidl. DO NOT MODIFY!";
	pidl " */";
	pidl "";
	pidl "#include \"includes.h\"";
	pidl "#include \"nterr.h\"";
	pidl "";
	pidl "#undef DBGC_CLASS";
	pidl "#define DBGC_CLASS DBGC_RPC";
	pidl "";

	foreach (@$ndr) {
		ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
	}

	return $res;
}

1;
