package Sparrow::Misc;

use strict;

use base 'Exporter';
use Carp;
use YAML qw{LoadFile};

use File::Path qw(make_path remove_tree);
use File::Touch;
use HTTP::Tiny;

use Sparrow::Constants;

our @EXPORT = qw {
    execute_shell_command 
    usage
    init_sparrow_env
    sparrow_config
    get_http_resource    
};

my $sparrow_config;

sub execute_shell_command {

    my $cmd = shift;
    my %opts = @_;

    my $st = ( system($cmd) == 0 );

    if ($opts{silent}){
        die "failed to execute shell command" unless $st;
    } else {
        confess "failed to execute shell command: $cmd" unless $st;
    }
}

sub usage {

    print "usage: sparrow index|plg|project|task action args\n\n";

    print "action examples:\n\n";

    print "\[index]:\n\n";
    print "\tsparrow index update  # get freash index from SparrowHub\n";
    print "\tsparrow index summary # print cached index summary\n";

    print "\n[projects]:\n\n";
    print "\tsparrow project create foo # create a project\n";
    print "\tsparrow project remove foo # remove a project\n";
    print "\tsparrow project show foo   # get project info\n";
    print "\tsparrow project list       # list projects\n";

    print "\n[plugins]:\n\n";

    print "\tsparrow plg search foo          # search plugins \n";
    print "\tsparrow plg list                # show installed plugins \n";
    print "\tsparrow plg install df-check    # install plugin \n";
    print "\tsparrow plg remove  df-check    # remove plugin\n";
    print "\tsparrow plg show    df-check    # get plugin info\n";
    print "\tsparrow plg man     df-check    # get plugin manual\n";
    print "\tsparrow plg run     df-check    # run plguin tests\n";


    print "\n[tasks]:\n\n";
    print "\tsparrow task add         system disk df-check    # create task named `disk' tied to plugin df-check in project system\n";
    print "\tsparrow task remove      system disk             # remove task named `disk' in project foo\n";
    print "\tsparrow task show        system disk             # get `disk' task info \n";
    print "\tsparrow task run         system disk             # run `disk' task \n";
    print "\tsparrow task ini         system disk             # populate task plugin configuration \n";
    print "\tsparrow task load_ini    system disk /path/to/ini/file # load plugin configuration from file \n";
    print "\tsparrow task list                                # get tasks and projects list \n";
    print "\tsparrow task save        /var/data/tasks         # save current tasks to directory \n";
    print "\tsparrow task restore     /var/data/tasks         # restore tasks from directory \n";
    print "\tsparrow task copy        p1/t1 p2/t2             # copy task between projects \n";

    print "\n[task boxes]:\n\n";
    print "\tsparrow box run /path/to/box.json # run task box \n";

    print "\n[remote tasks]:\n\n";
    print "\tsparrow remote task upload  utils/git-setup        # upload task named `git-setup' to your SparrowHub account\n";
    print "\tsparrow remote task install utils/git-setup        # install your remote task utils/git-setup\n";
    print "\tsparrow remote task install john\@utils/git-setup   # install John's remote task utils/git-setup\n";
    print "\tsparrow remote task share utils/git-setup          # share task named `git-setup' \n";
    print "\tsparrow remote task hide utils/git-setup           # hide task named `git-setup' \n";
    print "\tsparrow remote task list                           # list your remote tasks\n";
    print "\tsparrow remote task public list                    # list public remote tasks\n";
    print "\tsparrow remote task remove utils/git-setup         # remove remote task named `git-setup' \n";

    print "\n\n";

    print "follow https://github.com/melezhik/sparrow to get full documentation\n";

}




sub init_sparrow_env {

    make_path(sparrow_root());
	print "sparrow root: [", sparrow_root(),"]\n";
	make_path(sparrow_root().'/plugins', { verbose => 1 } ); #
    make_path(sparrow_root().'/plugins/private');
    make_path(sparrow_root().'/plugins/public');
    make_path(sparrow_root().'/projects');
    #remove_tree(sparrow_root.'/cache');

    make_path(sparrow_root.'/cache');

    touch( spi_file(), spl_file(), spci_file() );

    if (-f sparrow_conf_file()){
      ($sparrow_config) = LoadFile(sparrow_conf_file());
    }
}

sub sparrow_config {
    $sparrow_config||{};
}

sub get_http_resource {

  my $url = shift;
  my %opts = @_;

  my $agent = $opts{agent} || 'http-tiny';
  my $res;	

  if ( -f $url ) {
		open my $fh1, $url or die "can't open $url to read: $!";
		$res = join "", <$fh1>;
		close $fh1;	
  } else {
    my $a = 1;
    my $s = 1;
		while (1){
      my $response = HTTP::Tiny->new( agent => $agent )->get($url);
      if ($response->{success}){
  		  $res = $response->{content};
        last;
      } elsif( $response->{code} == 599 ) { # retry N=3 times in case of "Network Connect Timeout" Error
        $a++;
        next if $a > 3; # N=3
        $s = $s*2;
        print "retrying to fetch the url ... attempt number $a, sleep $s seconds before\n";
        sleep($s);
      }
	  	die "Failed to fetch $url: $response->{status} $response->{reason}\n";
    }
  }
  return $res;
}

1;

