#!/usr/bin/perl

# ====================================================================
# The Vovida Software License, Version 1.0 
# 
# Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
#    and "Vovida Open Communication Application Library (VOCAL)" must
#    not be used to endorse or promote products derived from this
#    software without prior written permission. For written
#    permission, please contact vocal\@vovida.org.
# 
# 4. Products derived from this software may not be called "VOCAL", nor
#    may "VOCAL" appear in their name, without prior written
#    permission of Vovida Networks, Inc.
# 
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
# NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# 
# ====================================================================
# 
# This software consists of voluntary contributions made by Vovida
# Networks, Inc. and many individuals on behalf of Vovida Networks,
# Inc.  For more information on Vovida Networks, Inc., please see
# <http://www.vovida.org/>.

#  $Id: build-iface,v 1.6 2000/08/12 01:25:09 bogawa Exp $

# TODO


do "config-build.pl";

$parameter_count = 0;

open(IN, "request-parameter-matrix");

while(<IN>) {
    chomp;

    # remove lines starting with "#"
    s/^\#.*$//;


    @a = split(/\|/);

    if($a[1]) {

	shift(@a);
	
	
	foreach(@a) {
	    # kill leading/trailing whitespace
	    s/^\s*//;
	    s/\s*$//;
	    s/\*$//;
	}
	
	#| Parameter name      |  EP|  CR|  MD|  DL|  RQ|  NT|  AU|  AU|
	#|                     |  CF|  CX|  CX|  CX|  NT|  FY|  EP|  CX|
	#|_____________________|____|____|____|____|____|____|____|____|
	
	# ordering
	
	# 0   --  parameter name
	# 1   -- endpoint config
	# 2   -- create connection
	# 3   -- modify connection
	# 4   -- delete connection
	# 5   -- request notification
	# 6   -- notify
	# 7   -- audit endpoint
	# 8   -- audit connection
	
	$parameter_name[$parameter_count] = $a[0];
	
	for($i = 1; $i <= 8; $i++) {
	    $parameter_matrix->[$parameter_count][$i-1] = $a[$i];
	}
	$parameter_count++;
	
    }
}

close(IN);


$response_parameter_count = 0;
open(IN, "response-parameter-matrix");

while(<IN>) {
    chomp;

    # remove lines starting with "#"
    s/^\#.*$//;

    @a = split(/\|/);

    if($a[1]) {

	shift(@a);
	
	
	foreach(@a) {
	    # kill leading/trailing whitespace
	    s/^\s*//;
	    s/\s*$//;
	    s/\*$//;
	}
	
	#| Parameter name      |  EP|  CR|  MD|  DL|  RQ|  NT|  AU|  AU|
	#|                     |  CF|  CX|  CX|  CX|  NT|  FY|  EP|  CX|
	#|_____________________|____|____|____|____|____|____|____|____|
	
	# ordering
	
	# 0   --  parameter name
	# 1   -- endpoint config
	# 2   -- create connection
	# 3   -- modify connection
	# 4   -- delete connection
	# 5   -- request notification
	# 6   -- notify
	# 7   -- audit endpoint
	# 8   -- audit connection
	
#	$response_parameter_name[$parameter_count] = $a[0];
	
	for($i = 1; $i <= 8; $i++) {
	    $response_parameter_matrix->[$response_parameter_count][$i-1] = $a[$i];
	}
	$response_parameter_count++;
	
    }
}

close(IN);




open(IN, "parameter-types");
while(<IN>) {
    chomp;
    # remove lines starting with "#"
    s/^\#.*$//;

    @a = split(/ +/);

    $parameter_style{$a[2]} = $a[0];
    $parameter_type{$a[2]} = $a[1];
}
close(IN);



open(IN, "verb-data");

$verb_count = 0;

while(<IN>) {
    chomp;
    # remove lines starting with "#"
    s/^\#.*$//;

    @a = split(/\|/);

    
    if($a[1]) {

	foreach(@a) {
	    # kill leading/trailing whitespace
	    s/^\s*//;
	    s/\s*$//;
	}

	$verb_name[$verb_count] = $a[0];

	$verb_abbreviation[$verb_count] = $a[1];

	$class_direction[$verb_count] = $a[2];
	$verb_count++;
    }
}
close(IN);


open(MGC_CLASS, ">mgc.hxx");

print MGC_CLASS "#ifndef MGC_CLASS_H_\n";
print MGC_CLASS "#define MGC_CLASS_H_\n";

print MGC_CLASS "#include \"$mgc_events\"\n\n";
print MGC_CLASS "#include \"$generic_event_file\"\n\n";

print MGC_CLASS "///\n";
print MGC_CLASS "enum MgcCommandType\n";
print MGC_CLASS "{\n";

for($i = 0; $i < $verb_count ; $i++) {
    $class_name = "Mgc$verb_name[$i]";
    print MGC_CLASS "    $class_name", "Type,\n";
}

print MGC_CLASS "};\n";
print MGC_CLASS "\n\n";

print MGC_CLASS "class MgcCommand\n";
print MGC_CLASS "{\n";
print MGC_CLASS "public:\n";
print MGC_CLASS "};\n";


for($i = 0; $i < $verb_count ; $i++) {

    print MGC_CLASS "///\n";

    $class_name = "Mgc$verb_name[$i]";

    print MGC_CLASS "class $class_name : public MgcCommand\n";
    print MGC_CLASS "{\n";
    print MGC_CLASS "public: \n";

    $command_matrix = $parameter_matrix;
    $response_matrix = $response_parameter_matrix;

    &do_sender_side(MGC_CLASS);
}

print MGC_CLASS "#endif\n";

close(MGC_CLASS);



sub do_sender_side {
    local($fh) = $_[0];

    # do the stuff for each mandatory parameter

    $not_first_parameter = 0;
    $constructor_arguments = "";
    for($j = 0; $j < $parameter_count; $j++) {
	if($command_matrix->[$j][$i] eq "M") {
	    # mandatory parameter
	    if($not_first_parameter) {
		$constructor_arguments .= ", ";
	    }
	    $pn = $parameter_name[$j];
	    $constructor_arguments .= "const $parameter_type{$pn}& $pn";
	    $not_first_parameter = 1;
	}
    }

    print $fh "    ///\n";
    print $fh "    $class_name($constructor_arguments);\n";
    print $fh "\n";

    print $fh "    ///\n";
    print $fh "    MgcCommandType getType();\n";
    print $fh "\n";

    # now create the optional parameter accessors

    for($j = 0; $j < $parameter_count; $j++) {
	if($command_matrix->[$j][$i] eq "O") {
	    $pn = $parameter_name[$j];
	    # optional parameter
	    if($parameter_style{$pn} eq "normal") {
		print $fh "    ///\n";
		print $fh "    set$pn(const $parameter_type{$pn}& parameter);\n";
	    } elsif($parameter_style{$pn} eq "iter") {
		print $fh "    ///\n";
		print $fh "    add$pn(const $parameter_type{$pn}& parameter);\n";
		print $fh "    ///\n";
		print $fh "    clear$pn();\n";
	    }
	}
    }

    # now create the response accessors

    for($j = 0; $j < $response_parameter_count; $j++) {
	if(($response_matrix->[$j][$i] eq "O") || 
	  ($response_matrix->[$j][$i] eq "M")) {
	    $pn = $parameter_name[$j];
	    # optional parameter
	    if($parameter_style{$pn} eq "normal") {
		print $fh "    ///\n";
		print $fh "    $parameter_type{$pn} get$pn();\n";
	    } elsif($parameter_style{$pn} eq "iter") {
		print $fh "    ///\n";
		print $fh "    int getNum$pn();\n";
		print $fh "    ///\n";
		print $fh "    $parameter_type{$pn} getItem$pn(int index);\n";
	    }
	}
    }


    print $fh "};\n\n\n";
}




open(MG_CLASS, ">mg.hxx");

print MG_CLASS "#ifndef MG_CLASS_H_\n";
print MG_CLASS "#define MG_CLASS_H_\n";


print MG_CLASS "#include \"$mg_events\"\n\n";
print MG_CLASS "#include \"$generic_event_file\"\n\n";


# create the enum for the types of the commands

print MG_CLASS "///\n";
print MG_CLASS "enum MgCommandType\n";
print MG_CLASS "{\n";

for($i = 0; $i < $verb_count ; $i++) {
    $class_name = "Mg$verb_name[$i]";
    print MG_CLASS "    $class_name", "Type,\n";
}

print MG_CLASS "};\n";
print MG_CLASS "\n\n";

print MG_CLASS "class MgCommand\n";
print MG_CLASS "{\n";
print MG_CLASS "public:\n";
print MG_CLASS "};\n";






for($i = 0; $i < $verb_count ; $i++) {

    print MG_CLASS "///\n";

    $class_name = "Mg$verb_name[$i]";

    print MG_CLASS "class $class_name : public MgCommand\n";
    print MG_CLASS "{\n";
    print MG_CLASS "public: \n";

    # do the stuff for each mandatory parameter

    $command_matrix = $parameter_matrix;
    $response_matrix = $response_parameter_matrix;

    &do_response_side(MG_CLASS);

}

print MG_CLASS "#endif\n";

close(MG_CLASS);


sub do_response_side {
    local($fh) = $_[0];

    $not_first_parameter = 0;
    $constructor_arguments = "";
    for($j = 0; $j < $parameter_count; $j++) {
	if($command_matrix->[$j][$i] eq "M") {
	    # mandatory parameter
	    if($not_first_parameter) {
		$constructor_arguments .= ", ";
	    }
	    $pn = $parameter_name[$j];
	    $constructor_arguments .= "const $parameter_type{$pn}& $pn";
	    $not_first_parameter = 1;
	}
    }

    print $fh "    ///\n";
    print $fh "    $class_name($constructor_arguments);\n";
    print $fh "\n";

    print $fh "    ///\n";
    print $fh "    MgCommandType getType();\n";
    print $fh "\n";

    # now create the optional parameter accessors

    for($j = 0; $j < $parameter_count; $j++) {
	if(($command_matrix->[$j][$i] eq "O") || 
	   ($command_matrix->[$j][$i] eq "M")) {
	    $pn = $parameter_name[$j];
	    # optional parameter
	    if($parameter_style{$pn} eq "normal") {
		print $fh "    ///\n";
		print $fh "    $parameter_type{$pn} get$pn();\n";

	    } elsif($parameter_style{$pn} eq "iter") {
		print $fh "    ///\n";
		print $fh "    int getNum$pn();\n";
		print $fh "    ///\n";
		print $fh "    $parameter_type{$pn} getItem$pn(int index);\n";
	    }

	}
    }

    # now create the response accessors

    for($j = 0; $j < $response_parameter_count; $j++) {
	if(($response_matrix->[$j][$i] eq "O") ||
	   ($response_matrix->[$j][$i] eq "M")) {
	    $pn = $parameter_name[$j];
	    # optional parameter
	    if($parameter_style{$pn} eq "normal") {
		print $fh "    ///\n";
		print $fh "    set$pn(const $parameter_type{$pn}& parameter);\n";
	    } elsif($parameter_style{$pn} eq "iter") {
		print $fh "    ///\n";
		print $fh "    add$pn(const $parameter_type{$pn}& parameter);\n";
		print $fh "    ///\n";
		print $fh "    clear$pn();\n";
	    }
	}
    }


    print $fh "};\n\n\n";
}    

