#!/usr/bin/perl
use strict;
my($app_svnid) = '$HeadURL$ $LastChangedRevision$';
#  Allow bare words, so &ade_err_error() calls look nicer.
no strict 'subs';
use lib substr `ade-config ade_include_prefix`,0,-1;
use ADE;
use lib substr `js-config js_include_prefix`,0,-1;
use experimental 'smartmatch';
use IPC::SysV qw(IPC_PRIVATE IPC_RMID IPC_CREAT S_IRUSR S_IWUSR);
use Storable;
use lib substr `js-config js_include_prefix`,0,-1;
use JS;

my(%jsm_defined_errors) = (
    jsm_err_misc         => { fmt => "%s" },
);

#  Options
my(%opt_resources);

#  Other globals

sub jsm
{
    my($errstack_ref) = @_;
    my($rc, @select_results, $job_id, $command, $i, $sql_statement, $resource);
    my(@local_errstack);
    my($db_file, $jsd_pid, $running_flag);
    my($lock_file, $js_msgqueue_id, %reply, %message, $sender_id);

    #  Set ADE options
    &ade_err_registerdefderrs(\%jsm_defined_errors);
    &ade_err_resetstack($errstack_ref, dumpall=>0);

    #  Defaults for options 
    #  (identical line in jsd, jsm, jsq).

    #  Register options
    if (($rc=&ade_opt_register($errstack_ref, "", "", "main::jsm_opt_handler_%s")) != $ade_err_ok) {
        return($rc);
    }

    #  Register handler functions
    if (($rc=&ade_msg_register($errstack_ref, \&jsm_usage, \&jsm_version, \&jsm_listpaths)) != $ade_err_ok) {
        return($rc);
    } 

    #  Process options
    if (($rc=&ade_opt_process($errstack_ref)) != $ade_err_ok) {
        return($rc);
    } 

    #  Process arguments

    #  Sanity checks and derivations
    $lock_file = $ENV{JSD_LOCKFILE} ? $ENV{JSD_LOCKFILE} : "$ade_tmp_dir/jsd-$ENV{'LOGNAME'}.lock";
    if (($rc=&ade_lck_checklock($errstack_ref, $lock_file, \$jsd_pid, \$running_flag)) != $ade_err_ok) {
        &ade_err_debug($errstack_ref, 20, "ade_lck_lock: ade_lck_checklock failed");
        return($rc);
    }
    if (!$running_flag) {
        &ade_err_error($errstack_ref, jsm_err_misc, "jsd: not running");
        return($ade_err_fail);
    }
    if (!defined($js_msgqueue_id=msgget($js_msgqueue_key, S_IRUSR | S_IWUSR))) {
        &ade_err_error($errstack_ref, jsm_err_misc, "msgget: failed");
        return($ade_err_fail);
    }

    if (($rc=&list_to_hash($errstack_ref, \@ARGV, \%message)) != $ade_err_ok) {
        return($rc);
    }

    if (($rc=&send_message($errstack_ref, $js_msgqueue_id, $js_msgqueue_type_jsm, $js_msgqueue_type_jsd, \%message)) != $ade_err_ok) {
        return($rc);
    }

    if (($rc=&read_message($errstack_ref, $js_msgqueue_id, \$sender_id, $js_msgqueue_type_jsm, \%reply)) != $ade_err_ok) {
        return($rc);
    #  Jsd's call to read_message() might be interrupted by a signal arriving. Jsm's call should not be,
    #  so what is gracefully ignored in jsd generates an error in jsm.
    } elsif (not %message) {
        &ade_err_error($errstack_ref, jsm_err_misc, "read_message() failed, which is odd in jsm!");
        return($ade_err_fail);
    }
    &ade_err_debug($errstack_ref, 10, "reply{rc}=$reply{rc}, reply{text}=$reply{text}");
    if ($reply{rc} != 0) {
        &ade_err_error($errstack_ref, jsm_err_misc, $reply{text});
        return($ade_err_fail);
    } else {
        printf("%s\n", $reply{text});
    }

    #  Tidy up
    return ($ade_err_ok);
}

sub jsm_version
{
    my($errstack_ref, $version_text_ref) = @_;

    return(&ade_smf_extractversionfromsvnstring($errstack_ref, $app_svnid, $version_text_ref));
}

sub jsm_listpaths
{
    my($errstack_ref, $pathlist_text_ref) = @_;
    my($rc);

    #${$pathlist_text_ref} = "";

    return($ade_err_ok);
}

sub jsm_usage
{
    my($errstack_ref, $usage_text_ref, $passno) = @_;

    if ($passno == 1) {
        ${$usage_text_ref} = "\n";
    } elsif ($passno == 2) {
        ${$usage_text_ref} = "";
    }

    return($ade_err_ok);
}

sub list_to_hash
{
    my($errstack_ref, $list_ref, $hash_ref) = @_;

    my($key, $val, $item);

    %{$hash_ref} = ();
    foreach $item (@{$list_ref}) {
        if (!(($key,$val) = ($item=~/^([^=]+)=(.*)$/))) {
            &ade_err_error($errstack_ref, jsm_err_misc, "$item: failed to parse");
            return($ade_err_fail);
        }
        &ade_err_debug($errstack_ref, 10, "list_to_hash: key=$key, val=$val");
        ${$hash_ref}{$key} = $val;
    }

    return($ade_err_ok);
}

&ade_gep_main(\&jsm);
