#!/usr/bin/perl

=encoding UTF-8

=head1 DESCRIPTION

Cкрипт делает запросы в сокет поднятого Rosetta сервера

=head1 PARAMS

 beta_port   - порт беты с поднятым Rosetta сервером
 requests    - массив c пачкой запросов
    или для одного запроса:
 login       - под кем fake логинится
 model       - модель
 method      - метод
 args        - массив параметров


=head1 USAGE

> ./bin/rosetta_socket_call --beta_port=8010  \
   --model=frontend --method=find_resource \
   --args='["name", "public_id", "value", "R-I-92550-14"]'


> ./bin/rosetta_socket_call --beta_port=8010  --login=yndx-zurom \
  --requests='[
     {"model":"frontend", "method":"find_resource", "opts":{"name":"public_id", "value":"D-I-92550-14"}},
     {"model":"frontend", "method":"find_resource", "opts":{"name":"public_id", "value":"R-I-92550-14"}}
  ]'

=cut

# common modules
use strict;
use warnings FATAL => 'all';
use feature 'say';
use utf8;

use Pod::Usage;
use Getopt::Long qw();
use Data::Dumper;
use DDP;

use lib::abs '../lib';

use qbit;
use Utils::Logger qw(INFO WARN ERROR);
use Protocol::Rosetta::Client;
use Protocol::Rosetta::Request;


main();


sub main {

    say '#Start';

    my ($port, $login, $requests) = _get_args();

    my ( $ip, $client ) = _setup( $port );

    INFO '    send "fake_authorization" request';
    {
        my $request = Protocol::Rosetta::Request->new(
            type   => 'fake_authorization',
            login  => $login,
        );

        my $answer = $client->send( $request );
        #p $answer;
    }

    my $count = 0;
    foreach my $call_request ( @$requests ){
        INFO '    send "call" request #' . ++$count;

        my $opts = delete $call_request->{opts};
        $call_request->{args} = [ map { $_, $opts->{$_} } keys %$opts ]  if $opts;

        {
            my $request = Protocol::Rosetta::Request->new(
                type   => 'call',
                model  => $call_request->{model},
                method => $call_request->{method},
                args   => $call_request->{args},
            );

            my $answer = $client->send( $request );

            p $answer;
        }
    }

    say '#END';
}

sub _setup {
    my ($port) = @_;

    my $ip = '';
    {
        my $cmd = q[hostname  -I | awk '{print $1}'];
        $ip = `$cmd`; chomp $ip;
    }

    my $client = Protocol::Rosetta::Client->new(
        ip   => $ip,
        port => $port,
    );

    Utils::Logger::init_and_watch();

    return ( $ip, $client );
}

sub _get_args {

    my $beta_port = 0;
    my $login     = '';
    my $model     = '';
    my $method    = '';
    my $args      = undef;
    my $opts      = undef;
    my $requests  = undef;


    my $help = 0;
    Getopt::Long::GetOptions(
        #--- Obligatory
        'beta_port:s'  => \$beta_port,
        'login:s'      => \$login,
        'model:s'      => \$model,
        'method:s'     => \$method,
        'args:s'       => \$args,
        'requests:s'   => \$requests,
        #---
        'help|?|h' => \$help,
    ) or pod2usage(1);

    pod2usage(-verbose => 2, -noperldoc => 1) if $help;

    #-- Проверяем зн-ия входных параметров
    my $errors = [];
    if (!$beta_port && !$model && !$method && !$args) {
        push @$errors, 'request is empty';
    }

    push @$errors, 'beta_port is empty' unless $beta_port;
    push @$errors, 'login is empty'  unless $login;

    unless ($requests){
        push @$errors, 'model  is empty' unless $model;
        push @$errors, 'method is empty' unless $method;
        push @$errors, 'args is empty' unless $args;
    }

    if (@$errors) {
        print join("\n", @$errors), "\n";
        pod2usage(-verbose => 2, -noperldoc => 1);
        exit(0);
    }

    if ( $requests ) {
        $requests = from_json($requests);
    }
    else {
        my $json = sprintf '{"model":"%s","method":"%s","args":%s}', $model, $method, $args;
        $requests = [ from_json($json) ];
    }


    my $port = $beta_port + 10_000; # 8010 -> 18010

    return ($port, $login, $requests);
}
