package ILMT::URD::HIN::Morph;
use strict;
use warnings;
use Dir::Self;
use Data::Dumper;
use IO::Socket::INET;
use ILMT::URD::HIN::Morph::adj_gen;

my $cwd = __DIR__;

my %daemons = (
    "morph" => {
        "path" => "$cwd/Morph/analyser/morph_urd.exe",
        "args" => "--logfilepath $cwd/Morph/morph.log " .
                  "--pdgmfilepath $cwd/Morph/analyser/data/ " .
                  "--uwordpath $cwd/Morph/analyser/data/dict_final " .
                  "--dictfilepath $cwd/Morph/analyser/data/dict " .
                  "-ULDWH --tcpserver",
        "port" => "31002"
    },
    "nuqta_adder" => {
        "path" => "$cwd/Morph/nuqta-adder.py",
        "args" => "",
        "port" => "31003"
    }
);

my @dispatch_seq = (
    "remove_sentence_tag",
    "remove_ssf",
    "morph_analyser",
    "nuqta_adder_urd",
    "add_sentence_tag",
    "adjective_generator"
);

sub add_sentence_tag {
    my %par = @_;
    my $data = $par{'data'};
    open INFILE, '<', \$data  or die $!;
    my $result = "<Sentence id=\"1\">\n";
    while (my $line=<INFILE>) {
        $result .= $line;
    }
    $result .= "</Sentence>\n";
    return $result;
}

sub morph_analyser {
    my %args = @_;
    return call_daemon("morph", $args{data});
}

sub nuqta_adder_urd {
    my %args = @_;
    return call_daemon("nuqta_adder", $args{data});
}

sub process {
    my %args = @_;
    utf8::encode($args{"data"});
    foreach my $submodule (@dispatch_seq) {
        $args{'data'} = __PACKAGE__->can($submodule)->(%args);
    }
    utf8::decode($args{"data"});
    return $args{"data"};
}

sub remove_sentence_tag {
    my %par = @_;
    my $data = $par{'data'};
    open INFILE, '<', \$data or die $!;
    my $result = "";
    while(my $line=<INFILE>) {
        if($line=~/^</) {
            next;
        } else {
            $result .= $line;
        }
    }
    return $result;
}

sub remove_ssf {
    my %par = @_;
    my $data = $par{'data'};
    open INFILE, '<', \$data  or die $!;
    my $result = "";
    my $_prev = 1;
    while (my $line=<INFILE>) {
        if ($line=~m/^0\t/) {
            $_prev=2;
            next;
        } elsif ($line=~/^\t\)\)/ and $_prev=~/^\t\)\)/) {
            $_prev="\t))";
            next;
        } else {
            $_prev="$line";
            $result .= "$line";
        }
    }
    return $result;
}

sub run_daemons {
    my @daemon_names = @_;
    foreach my $daemon_name (@daemon_names) {
        my %daemon = %{$daemons{$daemon_name}};
        my $cmd = "$daemon{path} $daemon{args} $daemon{port} &";
        my $runfile = __DIR__ . "/run/${daemon_name}_$daemon{port}";
        system("flock -e -w 0.01 $runfile -c '$cmd'") == 0
            or warn "[" . __PACKAGE__ . "]: Port $daemon{port} maybe unavailable! $?\n";
    }
}

sub call_daemon {
    my ($daemon_name, $input) = @_;
    my $port = $daemons{$daemon_name}{port};
    my ($socket, $client_socket);
    $socket = new IO::Socket::INET (
        PeerHost => '127.0.0.1',
        PeerPort => $port,
        Proto => 'tcp',
    ) or die "ERROR in Socket Creation : $!\n";
    $socket->send("$input\n");
    my $result = "";
    while (my $line = $socket->getline) {
        $result .= $line;
    }
    $socket->close();
    return $result;
}

sub adjective_generator {
    my %par = @_;
    my $data = $par{'data'};
    my $result = "";
    adj_gen(\$data, \$result);
    return ($result);
}

run_daemons(("morph", "nuqta_adder"));

1;
