#!/usr/bin/perl
  
# usage: perl wabi-client conf.json
  
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request::Common;
use JSON qw/encode_json decode_json/;
  
&main;
  
sub main {
    my $json_file = $ARGV[0];
  
    # JSONファイルから値を取り出す。
    my $json_data = &read_json_file($json_file);
  
    # 入力ファイルを読む。
    my $post_data = &read_data($json_data);
  
    # 取り出した値をPOSTする。
    my $request_id = &post_data($$json_data{'url'}, $post_data);
  
    # 処理が終了するまで待つ。
    &check_status($$json_data{'url'}, $request_id);
  
    # mafftの出力結果を取得する。
    &get_result($$json_data{'url'}, $request_id);
}
  
sub read_json_file {
    my $json_file = $_[0];
  
    open IN, $json_file or die;
    my $json_in = '';
    while (<IN>) {
        chomp;
        $json_in .= $_;
    }
    close IN;
    my $data_ref = decode_json($json_in);
    return $data_ref;
}
  
sub read_data {
    my $json_data = $_[0];
  
    my %post_data = (
        'querySequence' => '',
        'profile1' => '',
        'profile2' => '',
        'aaMatrix' => '',
        'addSequence' => '',
        'addfragmentsSequence' => '',
        'addprofileProfile' => '',
        'addfullSequence' => '',
        'format' => 'text',
        'parameters' => $$json_data{'parameters'},
        'result' => $$json_data{'result'},
        'address' => $$json_data{'address'},
    );
  
    my @params = (
        'querySequence',
        'profile1',
        'profile2',
        'aaMatrix',
        'addSequence',
        'addfragmentsSequence',
        'addprofileProfile',
        'addfullSequence'
    );
  
    foreach my $param (@params) {
        if (exists $$json_data{$param}) {
            $post_data{$param} = &open_read($$json_data{$param});
        }
    }
  
    return \%post_data;
}
  
sub post_data {
    my $url = $_[0];
    my $post_data_ref = $_[1];
  
    my $request = POST($url, $post_data_ref);
    my $ua = LWP::UserAgent -> new;
    my $res = $ua -> request( $request );
  
    my $request_id = '';
    if ($res->is_success) {
        my $content = $res->content;
        if ($content =~ /requestId: (.*)/) {
            $request_id = $1;
        }
    } else {
        my $content = $res->content;
        print "$content\n";
        die $res->status_line;
    }
    print "request-ID: $request_id\n";
    return $request_id;
}
  
sub check_status {
    my $url = $_[0];
    my $request_id = $_[1];
  
    my $status = '';
    while (1) {
        my $request = GET($url . $request_id);
        my $ua = LWP::UserAgent -> new;
        my $res = $ua -> request( $request );
        if ($res->is_success) {
            my $content = $res->content;
            if ($content =~/status: (.*)/) {
                $status = $1;
            }
        } else {
            die $res->status_line;
        }
        print "$status\n";
        if ($status eq 'waiting') {
            sleep(10);
        } elsif ($status eq 'running') {
            sleep(10);
        } elsif ($status eq 'finished') {
            last;
        }
    }
}
  
sub get_result {
    my $url = $_[0];
    my $request_id = $_[1];
  
    my $request = GET($url . $request_id . '?info=result');
    my $ua = LWP::UserAgent -> new;
    my $res = $ua -> request( $request );
    if ($res->is_success) {
        open OUT, ">${request_id}.txt" or die;
        print OUT $res->content;
        close OUT;
        print "mafft result is outputed to ${request_id}.txt\n";
    } else {
        die $res->status_line;
    }
}
  
sub open_read {
    my $file = $_[0];
    my $content = '';
    open FILE, $file or die;
    while (<FILE>) {
        $content .= $_;
    }
    close FILE;
    return $content;
}
