#! /usr/bin/perl
# tool to generate a burt input file from a CSV spreadsheet
# author Yi Qiang, yqiang@jlab.org

use strict;
use warnings;

# subroutine to write BURT REQ file header
sub PrintHeader{
    my $output_file = $_[0];
    my $output_req = $_[1];
    print $output_file "--- Start BURT header\n";
    print $output_file "Time:     Thu Nov 11 11:11:11 2014\n";
    print $output_file "Login ID: hdsys (HallD System)\n";
    print $output_file "Eff  UID: 8373\n";
    print $output_file "Group ID: 971\n";
    print $output_file "Keywords: \n";
    print $output_file "Comments: \n";
    print $output_file "Type:     Absolute\n";
    print $output_file "Directory /gluonfs1/gluex/controls/epics/R3-14-12-3-1/app/scripts/AlarmBURT\n";
    print $output_file "Req File: REQS/",$output_req,"\n";
    print $output_file "--- End BURT header\n";
}

# subroutine to write alarm for analog records
sub WriteAnalogAlarm{
    my $pv = $_[0];
    my $alarm = $_[1];
    my $type = $_[2];
    my $svtype = $_[3];
    my $alarm_level = $_[4];
    my $req_file = $_[5];
    my $set_file = $_[6];
    my $reset_file = $_[7];
    my $db_file = $_[8];
    
    $type =~ tr/a-z/A-Z/;
    $svtype =~ tr/a-z/A-Z/;

    if($alarm ne ''){
	if(substr($alarm,0,1) =~ m/[a-z,A-Z]/){
	    print $db_file "record(ao, \"",$pv,":",$type,"Limit\"){\n";
	    print $db_file "  field(SCAN,\"passive\")\n";
	    print $db_file "  field(OUT, \"",$pv,".",$type," PP\")\n";
	    print $db_file "  field(DOL, \"",$alarm," CPP\")\n";
	    print $db_file "  field(OMSL,\"closed_loop\")\n";
	    print $db_file "}\n";
	}
	elsif(substr($alarm,1,1) =~ m/[a-z,A-Z]/){
	    substr($alarm,0,1) = "";
	    print $db_file "record(calcout, \"",$pv,":",$type,"Limit\"){\n";
	    print $db_file "  field(SCAN,\"passive\")\n";
	    print $db_file "  field(OUT, \"",$pv,".",$type," PP\")\n";
	    print $db_file "  field(INPA,\"",$alarm," CPP\")\n";
	    print $db_file "  field(CALC,\"-A\")\n";
	    print $db_file "  field(OOPT,\"On Change\")\n";
	    print $db_file "}\n";
	}
	else{
	    print $req_file   $pv,".",$type,"\n";
	    print $set_file   $pv,".",$type," 1 ",$alarm,"\n";
	    print $reset_file $pv,".",$type," 1 0\n";
	}
	print $req_file   $pv,".",$svtype,"\n";
	print $set_file   $pv,".",$svtype," 1 ",$alarm_level,"\n";
	print $reset_file $pv,".",$svtype," 1 0\n";
    }
}

# subroutine to write alarm for bool records
sub WriteBoolAlarm{
    my $pv = $_[0];
    my $alarm = $_[1];
    my $type = $_[2];
    my $req_file = $_[3];
    my $set_file = $_[4];
    my $reset_file = $_[5];
    
    $type =~ tr/a-z/A-Z/;

    if($alarm ne ''){
	print $req_file   $pv,".",$type,"\n";
	print $set_file   $pv,".",$type," 1 ",$alarm,"\n";
	print $reset_file $pv,".",$type," 1 0\n";
    }
}

# open input and output files
my $input_file = $ARGV[0];
my $output_req = $ARGV[1];
my $output_burt = $ARGV[2];
my $reset_burt = $ARGV[3];
my $alarm_db = $ARGV[4];

open(my $alarm_list, "<", $input_file) or die "Could not open $input_file: $!";
open(my $burt_file, ">", $output_burt) or die "Could not open $output_burt: $!";
open(my $req_file, ">", $output_req) or die "Could not open $output_req: $!";
open(my $reset_file, ">", $reset_burt) or die "Could not open $reset_burt: $!";
open(my $db_file, ">", $alarm_db) or die "Could not open $alarm_db: $!";

# print header
PrintHeader($burt_file,$output_req);
PrintHeader($reset_file,$output_req);

# print alarm levels
while(my $line =<$alarm_list>){
    if(substr($line,0,1) ne '#'){
	my @element = split(/,/,$line);
	my $pv   = $element[0];
	my $lolo = $element[1];
	my $low  = $element[2];
	my $high = $element[3];
	my $hihi = $element[4];
	my $zsv  = $element[5];
	my $osv  = $element[6];
	my $csv  = $element[7];

	WriteAnalogAlarm($pv,$lolo,'LOLO','LLSV',2,$req_file,$burt_file,$reset_file,$db_file);
	WriteAnalogAlarm($pv,$low, 'LOW', 'LSV', 1,$req_file,$burt_file,$reset_file,$db_file);
	WriteAnalogAlarm($pv,$high,'HIGH','HSV', 1,$req_file,$burt_file,$reset_file,$db_file);
	WriteAnalogAlarm($pv,$hihi,'HIHI','HHSV',2,$req_file,$burt_file,$reset_file,$db_file);

	WriteBoolAlarm($pv,$zsv,'ZSV',$req_file,$burt_file,$reset_file);
	WriteBoolAlarm($pv,$osv,'OSV',$req_file,$burt_file,$reset_file);
	WriteBoolAlarm($pv,$csv,'CSV',$req_file,$burt_file,$reset_file);
    }
}
# done
print $output_burt,", ",$output_req," and ",$reset_burt," and ",$alarm_db," are generated.\n";
