package Net::FullAuto::ISets::Amazon::GNUSocial_is;

### OPEN SOURCE LICENSE - GNU AFFERO PUBLIC LICENSE Version 3.0 #######
#
#    Net::FullAuto - Distributed Workload Automation Software
#    Copyright © 2000-2016  Brian M. Kelly
#
#    This program is free software: you can redistribute it and/or
#    modify it under the terms of the GNU Affero General Public License
#    as published by the Free Software Foundation, either version 3 of
#    the License, or any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but **WITHOUT ANY WARRANTY**; without even the implied warranty
#    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public
#    License along with this program.  If not, see:
#    <http://www.gnu.org/licenses/agpl.html>.
#
#######################################################################

our $VERSION='0.01';
our $DISPLAY='GNU Social';
our $CONNECT='ssh';
our $defaultInstanceType='t2.micro';

my $service_and_cert_password='Full@ut0O1';

use 5.005;


use strict;
use warnings;

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw($select_gnusocial_setup);

use File::HomeDir;
my $home_dir=File::HomeDir->my_home.'/';

use Net::FullAuto::Cloud::fa_amazon;

my $configure_gnusocial=sub {

   my $server_type=$_[0];
   my $cnt=$_[1];
   my $selection=$_[2]||'';
   my $region=$_[4]||'';
   my $verified_email=$_[5]||'';
   my $permanent_ip=$_[6]||'';
   $permanent_ip='' if $permanent_ip=~/Stay|Reason/;
   if ($permanent_ip=~/Elastic/) {
      my $c="aws ec2 allocate-address --domain vpc";
      my ($hash,$output,$error)=run_aws_cmd($c);
      $hash||={};
      $permanent_ip=$hash->{PublicIp}; 
   }
   my $handle=$main::aws->{$server_type}->[$cnt]->[1];
   my ($stdout,$stderr)=('','');
   ($stdout,$stderr)=$handle->cmd("sudo yum -y update",'__display__');
   ($stdout,$stderr)=$handle->cmd("sudo yum clean all",'__display__');
   ($stdout,$stderr)=$handle->cmd("sudo yum grouplist hidden",'__display__');
   ($stdout,$stderr)=$handle->cmd("sudo yum groups mark convert",
      '__display__');
   ($stdout,$stderr)=$handle->cmd(
      'sudo yum -y install cyrus-sasl-plain send-mail-cf m4 java java-devel',
      '__display__');
   my $install_gnusocial=<<'END';

           o o    o .oPYo. ooooo    .oo o     o     o o    o .oPYo.
           8 8b   8 8        8     .P 8 8     8     8 8b   8 8    8
           8 8`b  8 `Yooo.   8    .P  8 8     8     8 8`b  8 8
           8 8 `b 8     `8   8   oPooo8 8     8     8 8 `b 8 8   oo
           8 8  `b8      8   8  .P    8 8     8     8 8  `b8 8    8
           8 8   `8 `YooP'   8 .P     8 8oooo 8oooo 8 8   `8 `YooP8
           ........................................................
           ::::::::::::::::::::::::::::::::::::::::::::::::::::::::


                           https://gnu.io/social/

                        ____ _   _ _   _     ____             _       _
        ,= ,-_-. =.    / ___| \ | | | | |   / ___|  ___   ___(_) __ _| | 
       ((_/)o o(\_))  | |  _|  \| | | | |   \___ \ / _ \ / __| |/ _` | |  
        `-'(. .)`-'   | |_| | |\  | |_| |    ___) | (_) | (__| | (_| | | 
            \_/        \____|_| \_|\___/    |____/ \___/ \___|_|\__,_|_| 


 (The Free Software Foundation is **NOT** a sponsor of the FullAuto© Project.)

END
   print $install_gnusocial;sleep 10;
   ($stdout,$stderr)=$handle->cmd(
      'sudo yum -y install php55 php55-curl php55-gd php55-gmp '.
      'php55-intl php55-json php55-opcache php55-mysqlnd '.
      'php55-mbstring php55-devel php55-fpm openssl-devel',
      '__display__');
   ($stdout,$stderr)=$handle->cmd(
      "sudo yum -y groupinstall 'Development tools'",'__display__');
   ($stdout,$stderr)=$handle->cmd(
      "sudo pecl install mailparse-2.1.6",'__display__');
   ($stdout,$stderr)=$handle->cmd('sudo '.
      "wget --random-wait --progress=dot ".
      "https://github.com/salimane/sphinx-0.9.9/archive/master.zip",
      '__display__');
   ($stdout,$stderr)=$handle->cmd("unzip master.zip",'__display__');
   ($stdout,$stderr)=$handle->cwd(
      "sphinx-0.9.9-master/api/libsphinxclient");
   ($stdout,$stderr)=$handle->cmd("./configure",'__display__');
   ($stdout,$stderr)=$handle->cmd("sudo make install",'__display__');
   ($stdout,$stderr)=$handle->cwd("-");
   ($stdout,$stderr)=$handle->cmd("sudo rm -rfv master.zip",'__display__');
   ($stdout,$stderr)=$handle->cmd("sudo rm -rfv sphinx-0.9.9-master",
      '__display__');
   ($stdout,$stderr)=$handle->cmd(
      "yes '' | sudo pecl install sphinx",'__display__');
   my $ad=<<END;
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/5.5/centos6-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
END
   ($stdout,$stderr)=$handle->cmd(
      "echo -e \"$ad\" > maria.repo");
   ($stdout,$stderr)=$handle->cmd(
      "sudo yum-config-manager --add-repo maria.repo",'__display__');
   ($stdout,$stderr)=$handle->cmd(
      "sudo rpm --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB",
      '__display__');
   ($stdout,$stderr)=$handle->cmd(
      "sudo yum -y install MariaDB-server MariaDB-client",'__display__');
print "\n\n\n\n\n\n\nWE SHOULD HAVE INSTALLED MARIADB=$stdout<==\n\n\n\n\n\n\n";
   ($stdout,$stderr)=$handle->cmd("uname -a");
   if ($stdout=~/Ubuntu/i) {
      ($stdout,$stderr)=$handle->cmd(
         "sudo apt-get -y install git-all",'__display__');
   } else {
      ($stdout,$stderr)=$handle->cmd(
         "sudo yum -y -v install git-all",'__display__');
   }
   ($stdout,$stderr)=$handle->cmd(
      "git clone -v https://git.gnu.io/gnu/gnu-social.git",'__display__');
   ($stdout,$stderr)=$handle->cmd(
      "sudo cp -Rv gnu-social /var/www/gnusocial",'__display__');
   ($stdout,$stderr)=$handle->cwd('/var/www/gnusocial');
   ($stdout,$stderr)=$handle->cmd("sudo wget -qO- http://icanhazip.com");
   my $public_ip=$stdout if $stdout=~/^\d+\.\d+\.\d+\.\d+\s*/s;
   unless ($public_ip) {
      require Sys::Hostname;
      import Sys::Hostname;
      require Socket;
      import Socket;
      my($addr)=inet_ntoa((gethostbyname(Sys::Hostname::hostname))[4]);
      $public_ip=$addr if $addr=~/^\d+\.\d+\.\d+\.\d+\s*/s;
   }
   chomp($public_ip);
   if ($public_ip && $permanent_ip) {
      my $c="aws ec2 describe-instances";
      my ($hash,$output,$error)=run_aws_cmd($c);
      $hash||={};
      $c="aws ec2 describe-addresses";
      my ($hasha,$outputa,$errora)=run_aws_cmd($c);
      $hasha||={};$hasha->{Addresses}||=[];
      my $a_id='';
      foreach my $address (@{$hasha->{Addresses}}) {
         if ($permanent_ip eq $address->{PublicIp}) {
            $a_id=$address->{AllocationId};
            last;
         }
      }
      my %pubip=();my $instance_id='';
      foreach my $res (@{$hash->{Reservations}}) {
         foreach my $inst (@{$res->{Instances}}) {
            my $pip=$inst->{PublicIpAddress}||'';
            my $iid=$inst->{InstanceId}||'';
            next if exists $inst->{State}->{Name} &&
               $inst->{State}->{Name} eq 'terminated';
            if ($public_ip eq $pip) {
               my $c="aws ec2 associate-address --instance-id ".
                     $inst->{InstanceId}." --allocation-id $a_id ".
                     "--allow-reassociation";
               my ($hasha,$outputa,$errora)=run_aws_cmd($c);
               $public_ip=$permanent_ip;
               last;
            }
         }
      } 
   }
   $public_ip='localhost' unless $public_ip;
   my $sudo='sudo ';
   # https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx
   #    -dont-trust-the-tutorials-check-your-configuration/
   # https://www.digitalocean.com/community/tutorials/
   #    understanding-and-implementing-fastcgi-proxying-in-nginx
   # http://dev.soup.io/post/1622791/I-managed-to-get-nginx-running-on
   # https://www.sitepoint.com/setting-up-php-behind-nginx-with-fastcgi/
   # http://codingsteps.com/install-php-fpm-nginx-mysql-on-ec2-with-amazon-linux-ami/
   # http://code.tutsplus.com/tutorials/revisiting-open-source-social-networking-installing-gnu-social--cms-22456
   # https://wiki.loadaverage.org/gnusocial/installation_guides/install_like_loadaverage
   # https://karp.id.au/social/index.html
   # http://jeffreifman.com/how-to-install-your-own-private-e-mail-server-in-the-amazon-cloud-aws/
   # http://www.linuxveda.com/2015/06/05/gnu-social-vs-twitter/
   my $nginx='nginx-1.10.0';
   $nginx='nginx-1.9.13' if $^O eq 'cygwin';
   ($stdout,$stderr)=$handle->cmd("sudo wget --random-wait --progress=dot ".
      "http://nginx.org/download/$nginx.tar.gz",'__display__');
   ($stdout,$stderr)=$handle->cmd("sudo tar xvf $nginx.tar.gz",'__display__');
   ($stdout,$stderr)=$handle->cwd($nginx);
   ($stdout,$stderr)=$handle->cmd("sudo mkdir -vp objs/lib",'__display__');
   ($stdout,$stderr)=$handle->cwd("objs/lib");
   my $pcre='pcre-8.38';
   my $checksum='';
   foreach my $cnt (1..3) {
      ($stdout,$stderr)=$handle->cmd("sudo wget --random-wait --progress=dot ".
         "ftp://ftp.csx.cam.ac.uk/pub/software/".
         "programming/pcre/$pcre.tar.gz",'__display__');
      ($stdout,$stderr)=$handle->cmd("sudo tar xvf $pcre.tar.gz",'__display__');
      last unless $stderr;
   }
   my $zlib='zlib-1.2.8';
   ($stdout,$stderr)=$handle->cmd("sudo wget --random-wait --progress=dot ".
      "http://zlib.net/$zlib.tar.gz",'__display__');
   $checksum='44d667c142d7cda120332623eab69f40';
   ($stdout,$stderr)=$handle->cmd(
      "sudo md5sum -c - <<<\"$checksum $zlib.tar.gz\"",
      '__display__');
   unless ($stderr) {
      print(qq{ + CHECKSUM Test for $zlib *PASSED* \n});
   } else {
      ($stdout,$stderr)=$handle->cmd("sudo rm -rvf $zlib.tar.gz",'__display__');
      my $dc=1;
      print "FATAL ERROR! : CHECKSUM Test for $zlib.tar.gz *FAILED* ",
            "after $dc attempts\n";
      &Net::FullAuto::FA_Core::cleanup;
   }
   ($stdout,$stderr)=$handle->cmd("sudo tar xvf $zlib.tar.gz",'__display__');
   my $ossl='openssl-1.0.2h';
   $checksum='577585f5f5d299c44dd3c993d3c0ac7a219e4949';
   ($stdout,$stderr)=$handle->cmd("sudo wget --random-wait --progress=dot ".
      "https://www.openssl.org/source/$ossl.tar.gz",
      '__display__');
   ($stdout,$stderr)=$handle->cmd(
      "sudo sha1sum -c - <<<\"$checksum $ossl.tar.gz\"",
      '__display__');
   unless ($stderr) {
      print(qq{ + CHECKSUM Test for $ossl *PASSED* \n});
   } else {
      ($stdout,$stderr)=$handle->cmd("sudo rm -rvf $ossl.tar.gz",'__display__');
      my $dc=1;
      print "FATAL ERROR! : CHECKSUM Test for $ossl.tar.gz *FAILED* ",
            "after $dc attempts\n";
      &Net::FullAuto::FA_Core::cleanup;
   }
   ($stdout,$stderr)=$handle->cmd("sudo tar xvf $ossl.tar.gz",'__display__');
   ($stdout,$stderr)=$handle->cwd("../..");
   my $make_nginx='sudo ./configure --sbin-path=/usr/local/nginx/nginx '.
                  '--conf-path=/usr/local/nginx/nginx.conf '.
                  '--pid-path=/usr/local/nginx/nginx.pid '.
                  "--with-http_ssl_module --with-pcre=objs/lib/$pcre ".
                  "--with-zlib=objs/lib/$zlib";
   ($stdout,$stderr)=$handle->cmd($make_nginx,'__display__');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i 's/-Werror //' ./objs/Makefile");
   ($stdout,$stderr)=$handle->cmd("${sudo}make install",'__display__');
   # https://www.liberiangeek.net/2015/10/
   # how-to-install-self-signed-certificates-on-nginx-webserver/
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}mkdir -vp /etc/nginx/ssl.key");
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}mkdir -vp /etc/nginx/ssl.crt");
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}mkdir -vp /etc/nginx/ssl.csr");
   $handle->{_cmd_handle}->print(
      "${sudo}openssl genrsa -des3 -out ".
      "/etc/nginx/ssl.key/$public_ip.key 2048");
   my $prompt=substr($handle->{_cmd_handle}->prompt(),1,-1);
   $prompt=~s/\$$//;
   while (1) {
      my $output.=Net::FullAuto::FA_Core::fetch($handle);
      last if $output=~/$prompt/;
      print $output;
      if (-1<index $output,'pass phrase for') {
         $handle->{_cmd_handle}->print($service_and_cert_password);
         $output='';
         next;
      } elsif (-1<index $output,'Verifying - Enter') {
         $handle->{_cmd_handle}->print($service_and_cert_password);
         $output='';
         next;
      }
   }
   while (1) {
      my $trys=0;
      my $ereturn=eval {
         local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
         alarm 7;
         $handle->{_cmd_handle}->print(
            "${sudo}openssl req -new -key /etc/nginx/ssl.key/$public_ip.key ".
            "-out /etc/nginx/ssl.csr/$public_ip.csr");
         my $test='';my $output='';
         while (1) {
            $output.=Net::FullAuto::FA_Core::fetch($handle);
            $test.=$output;
            $test=~tr/\0-\11\14-\37\177-\377//d;
            return 'DONE' if $output=~/$prompt/;
            print $output;
            $test=~s/\n//gs;
            if ($test=~/Enter pass phrase.*key:/s) {
               $handle->{_cmd_handle}->print($service_and_cert_password);
               $output='';
               $test='';
               next;
            } elsif ((-1<index $test,'[AU]:') ||
                  (-1<index $test,'[XX]:')) {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            } elsif ((-1<index $test,'[Some-State]:') ||
                  (-1<index $test,'State or Province')) {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            } elsif (-1<index $test,'city') {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            } elsif ((-1<index $test,'Pty Ltd]:') ||
                  (-1<index $test,'company')) {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            } elsif (-1<index $test,'section) []:') {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            } elsif ((-1<index $test,'YOUR name) []:') ||
                  (-1<index $test,'Common Name')) {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            } elsif (-1<index $test,'Address []:') {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            } elsif (-1<index $test,'challenge password []:') {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            } elsif (-1<index $test,'company name []:') {
               $handle->{_cmd_handle}->print();
               $output='';
               $test='';
               next;
            }
         }
         return 'DONE';
      };
      alarm(0);
      last if $ereturn eq 'DONE' || $trys++>3;
   }
   $handle->{_cmd_handle}->print(
      "${sudo}openssl x509 -req -days 365 -in ".
      "/etc/nginx/ssl.csr/$public_ip.csr -signkey ".
      "/etc/nginx/ssl.key/$public_ip.key -out ".
      "/etc/nginx/ssl.crt/$public_ip.crt");
   while (1) {
      my $output.=Net::FullAuto::FA_Core::fetch($handle);
      last if $output=~/$prompt/;
      print $output;
      if (-1<index $output,'Enter pass phrase') {
         $handle->{_cmd_handle}->print($service_and_cert_password);
         $output='';
         next;
      }
   }
   ($stdout,$stderr)=$handle->cmd("${sudo}sed -i 's/1024/64/' ".
      "/usr/local/nginx/nginx.conf");
   $ad="          proxy_http_version 1.1;%NL%".
       "          proxy_set_header Connection \"\";%NL%".
       "          include fastcgi_params;%NL%".
       "          fastcgi_param SCRIPT_FILENAME ".
       '/var/www/gnusocial/$fastcgi_script_name;%NL%'.
       "          fastcgi_pass unix:/var/run/php-fpm/php5-fpm.sock;%NL%".
       "          fastcgi_index index.php;";
   $ad=<<END;
sed -i '1,/location/ {/location/a\\\
$ad
}' /usr/local/nginx/nginx.conf
END
   $handle->cmd_raw("${sudo}$ad");
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i 's#^[ ]*location / {#        location ~ \\.php {#' ".
       '/usr/local/nginx/nginx.conf');
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i '/ location ~/iroot /var/www/gnusocial;' ".
       '/usr/local/nginx/nginx.conf');
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i '/ location ~/".
       "iindex index.php index.html index.htm;%NL%' ".
       '/usr/local/nginx/nginx.conf');
   $handle->cmd_raw(
       "${sudo}sed -i 's#\\(^root /var/www/gnusocial;$\\\)#        \\1#' ".
       '/usr/local/nginx/nginx.conf');
   $handle->cmd_raw("${sudo}sed -i ".
       "'s#\\(^index index.php index.html index.htm;$\\\)#        \\1#' ".
       '/usr/local/nginx/nginx.conf');
   $ad='%NL%        location / {%NL%           try_files $uri $uri/ '.
       '@gnusocial;%NL%        }%NL%%NL%        location @gnusocial {'.
       '%NL%           rewrite ^(.*)$ /index.php?p=$1 last;%NL%'.
       '        }';
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i \'/#error_page/a$ad\' /usr/local/nginx/nginx.conf");
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
       "/usr/local/nginx/nginx.conf");
   # https://www.linode.com/docs/websites/nginx/nginx-and-phpfastcgi-on-centos-5
   $ad='%NL%        location /static {'.
       "%NL%            root /var/www/gnusocial/root;".
       '%NL%        }%NL%'.
       '%NL%        ssl on;'.
       "%NL%        ssl_certificate /etc/nginx/ssl.crt/$public_ip.crt;".
       "%NL%        ssl_certificate_key /etc/nginx/ssl.key/$public_ip.key;".
       '%NL%        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;'.
       '%NL%        ssl_ciphers '.
       '"HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";';
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i \'/404/a$ad\' /usr/local/nginx/nginx.conf");
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
       "/usr/local/nginx/nginx.conf");
   $ad='%NL%'.
       '    server {%NL%'.
       '       listen 80;%NL%'.
       '       #listen [::]:80;%NL%'.
       '%NL%'.
       '       server_name  localhost;%NL%'.
       '%NL%'.
       '       # FIXME: change domain name here (and also make sure '.
       'you do the same in the next %SQ%server%SQ% section)%NL%'.
       '%NL%'.
       '       # redirect all traffic to HTTPS%NL%'.
       '       # rewrite ^ https://\$server_name\$request_uri? permanent;%NL%'.
       "       rewrite ^ https://$public_ip\$request_uri? permanent;%NL%".
       '    }';
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i \'/#gzip/a$ad\' /usr/local/nginx/nginx.conf");
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
       '/usr/local/nginx/nginx.conf');
   ($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" ".
       '/usr/local/nginx/nginx.conf');
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i \'s/^        listen       80/        listen       ".
       "\*:443 ssl default_server/\' /usr/local/nginx/nginx.conf");
   #($stdout,$stderr)=$handle->cmd("${sudo}sed -i 's/SCRIPT_NAME/PATH_INFO/' ".
   #    '/usr/local/nginx/nginx.conf');
   #$ad='# Catalyst requires setting PATH_INFO (instead of SCRIPT_NAME)'.
   #    ' to \$fastcgi_script_name';
   #($stdout,$stderr)=$handle->cmd(
   #    "${sudo}sed -i \'/PATH_INFO/i$ad\' /usr/local/nginx/nginx.conf");
   #$ad='fastcgi_param  SCRIPT_NAME        /;';
   #($stdout,$stderr)=$handle->cmd(
   #    "${sudo}sed -i \'/PATH_INFO/a$ad\' /usr/local/nginx/nginx.conf");
   #($stdout,$stderr)=$handle->cmd(
   #    "${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
   #    '/usr/local/nginx/nginx.conf');
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i \'s/nobody/ec2-user/\' ".
       '/usr/local/nginx/nginx.conf');
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i \'s/#user/user/\' ".
       '/usr/local/nginx/nginx.conf');
   ($stdout,$stderr)=$handle->cmd(
       "${sudo}sed -i '/^          fastcgi_index/{n;N;d}' ".
       '/usr/local/nginx/nginx.conf');
   $handle->{_cmd_handle}->print("${sudo}/usr/local/nginx/nginx");
   $prompt=substr($handle->{_cmd_handle}->prompt(),1,-1);
   while (1) {
      my $output.=Net::FullAuto::FA_Core::fetch($handle);
      last if $output=~/$prompt/;
      print $output;
      if (-1<index $output,'PEM pass phrase') {
         $handle->{_cmd_handle}->print($service_and_cert_password);
         $output='';
         next;
      }
   }
   ($stdout,$stderr)=$handle->cmd("sudo /etc/init.d/mysql start",
      '__display__');
print "\n\n\n\n\n\n\nSTDERR=$stderr\n\n\n\n\n\n\n";
   if ($stderr) {
      ($stdout,$stderr)=$handle->cmd(
         "sudo yum -y install MariaDB-server MariaDB-client",'__display__');
      ($stdout,$stderr)=$handle->cmd("sudo /etc/init.d/mysql start",
         '__display__');
   }
   $handle->{_cmd_handle}->print('sudo mysql_secure_installation');
   $prompt=substr($handle->{_cmd_handle}->prompt(),1,-1);
   while (1) {
      my $output=Net::FullAuto::FA_Core::fetch($handle);
      last if $output=~/$prompt/;
      print $output;
      if (-1<index $output,'root (enter for none):') {
         $handle->{_cmd_handle}->print();
         next;
      } elsif (-1<index $output,'Set root password? [Y/n]') {
         $handle->{_cmd_handle}->print('n');
         next;
      } elsif (-1<index $output,'Remove anonymous users? [Y/n]') {
         $handle->{_cmd_handle}->print('Y');
         next;
      } elsif (-1<index $output,'Disallow root login remotely? [Y/n]') {
         $handle->{_cmd_handle}->print('Y');
         next;
      } elsif (-1<index $output,
            'Remove test database and access to it? [Y/n]') {
         $handle->{_cmd_handle}->print('Y');
         next;
      } elsif (-1<index $output,'Reload privilege tables now? [Y/n]') {
         $handle->{_cmd_handle}->print('Y');
         next;
      }
   }
   $handle->cmd("echo");
   $handle->{_cmd_handle}->print('mysql -u root -p 2>&1');
   my $first_pass=0;
   my $second_pass=0;
   my $third_pass=0;
   my $fourth_pass=0;
   while (1) {
      my $output=Net::FullAuto::FA_Core::fetch($handle);
      last if $output=~/$prompt/ && $first_pass;
      print $output;
      if (-1<index $output,'Enter password:') {
         $handle->{_cmd_handle}->print();
         next;
      } elsif (-1<index $output,'none') {
         if (!$first_pass) {
            $handle->{_cmd_handle}->print('CREATE DATABASE gnusocial;');
            $first_pass=1;
         } elsif (!$second_pass) {
            $handle->{_cmd_handle}->print(
               'GRANT USAGE ON gnusocial.* TO gnusocial@localhost'.
               ' IDENTIFIED BY \'goodrandompassword\';');
            $second_pass=1;
         } elsif (!$third_pass) {
            $handle->{_cmd_handle}->print(
               'GRANT ALL PRIVILEGES ON gnusocial.* TO gnusocial@localhost;');
            $third_pass=1;
         } elsif (!$fourth_pass) {
            $handle->{_cmd_handle}->print('flush privileges;');
            $fourth_pass=1;
         } else {
            $handle->{_cmd_handle}->print('exit;');
         }
      }
   }
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i \'s#127.0.0.1:9000#/var/run/php-fpm/php5-fpm.sock#\' ".
      '/etc/php-fpm-5.5.d/www.conf');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i \'s/;listen.owner = nobody/listen.owner = ec2-user/\' ".
      '/etc/php-fpm-5.5.d/www.conf');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i \'s/;listen.group = nobody/listen.group = ec2-user/\' ".
      '/etc/php-fpm-5.5.d/www.conf');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i \'s/user = apache/user = ec2-user/\' ".
      '/etc/php-fpm-5.5.d/www.conf');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i \'s/group = apache/group = ec2-user/\' ".
      '/etc/php-fpm-5.5.d/www.conf');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}sed -i \'s/;listen.mode = 0660/listen.mode = 0664/\' ".
      '/etc/php-fpm-5.5.d/www.conf');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}chgrp -Rv ec2-user /var/lib/php/5.5/session ".
      '/var/lib/php/5.5/wsdlcache','__display__');
   ($stdout,$stderr)=$handle->cmd("${sudo}/etc/init.d/php-fpm start");
   ($stdout,$stderr)=$handle->cwd("/var/www/gnusocial");
   ($stdout,$stderr)=$handle->cmd("${sudo}chgrp -v ec2-user .");
   ($stdout,$stderr)=$handle->cmd("${sudo}chmod -v g+w .");
   ($stdout,$stderr)=$handle->cmd("${sudo}mkdir -v avatar background file");
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}chmod -v g+w avatar background file",'__display__');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}chmod -v a+w avatar background file",'__display__');
   ($stdout,$stderr)=$handle->cmd(
      "${sudo}chgrp -v ec2-user avatar background file",'__display__');
   #
   # echo-ing/streaming files over ssh can be tricky. Use echo -e
   #          and replace these characters with thier HEX
   #          equivalents (use an external editor for quick
   #          search and replace - and paste back results.
   #          use copy/paste or cat file and copy/paste results.):
   #
   #          !  -   \\x21
   #          "  -   \\x22
   #          $  -   \\x24
   #
   # https://www.lisenet.com/2014/ - bash approach to conversion
   my ($hash,$output,$error)=('','','');
   my $c="aws iam list-access-keys --user-name gnusocial_email";
   ($hash,$output,$error)=run_aws_cmd($c);
   $hash||={};
   foreach my $hash (@{$hash->{AccessKeyMetadata}}) {
      my $c="aws iam delete-access-key --access-key-id $hash->{AccessKeyId} ".
            "--user-name gnusocial_email";
      ($hash,$output,$error)=run_aws_cmd($c);
   }
   sleep 1;
   $c="aws iam delete-user --user-name gnusocial_email";
   ($hash,$output,$error)=run_aws_cmd($c);
   $c="aws iam create-user --user-name gnusocial_email";
   ($hash,$output,$error)=run_aws_cmd($c);
   $c="aws iam create-access-key --user-name gnusocial_email";
   ($hash,$output,$error)=run_aws_cmd($c);
   $hash||={};
   my $java_smtp_generator=<<END;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

public class SesSmtpCredentialGenerator {

       // From http://docs.aws.amazon.com/ses/latest/DeveloperGuide/smtp-credentials.html

       private static final String KEY_ENV_VARIABLE = \\x22AWS_SECRET_ACCESS_KEY\\x22; // Put your AWS secret access key in this environment variable.
       private static final String MESSAGE = \\x22SendRawEmail\\x22; // Used to generate the HMAC signature. Do not modify.
       private static final byte VERSION =  0x02; // Version number. Do not modify.

       public static void main(String[] args) {
    	       	   	
              // Get the AWS secret access key from environment variable AWS_SECRET_ACCESS_KEY.
              String key = System.getenv(KEY_ENV_VARIABLE);         	  
              if (key == null)
              {
                 System.out.println(\\x22Error: Cannot find environment variable AWS_SECRET_ACCESS_KEY.\\x22);  
                 System.exit(0);
              }
   	    	       	   
              // Create an HMAC-SHA256 key from the raw bytes of the AWS secret access key.
              SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), \\x22HmacSHA256\\x22);

              try {         	  
                     // Get an HMAC-SHA256 Mac instance and initialize it with the AWS secret access key.
                     Mac mac = Mac.getInstance(\\x22HmacSHA256\\x22);
                     mac.init(secretKey);

                     // Compute the HMAC signature on the input data bytes.
                     byte[] rawSignature = mac.doFinal(MESSAGE.getBytes());

                     // Prepend the version number to the signature.
                     byte[] rawSignatureWithVersion = new byte[rawSignature.length + 1];               
                     byte[] versionArray = {VERSION};                
                     System.arraycopy(versionArray, 0, rawSignatureWithVersion, 0, 1);
                     System.arraycopy(rawSignature, 0, rawSignatureWithVersion, 1, rawSignature.length);

                     // To get the final SMTP password, convert the HMAC signature to base 64.
                     String smtpPassword = DatatypeConverter.printBase64Binary(rawSignatureWithVersion);       
                     System.out.println(smtpPassword);
              } 
              catch (Exception ex) {
                     System.out.println(\\x22Error generating SMTP password: \\x22 + ex.getMessage());
              }             
       }
}
END
   ($stdout,$stderr)=$handle->cmd(
      "echo -e \"$java_smtp_generator\" > SesSmtpCredentialGenerator.java");
   ($stdout,$stderr)=$handle->cmd("javac SesSmtpCredentialGenerator.java");
   $handle->cmd_raw(
      "export AWS_SECRET_ACCESS_KEY=$hash->{AccessKey}->{SecretAccessKey}");
   my $smtppass='';
   ($smtppass,$stderr)=$handle->cmd("java SesSmtpCredentialGenerator");
   use LWP::UserAgent;
   use HTTP::Request::Common;
   use IO::Socket::SSL qw();
   my $Browser = LWP::UserAgent->new(
      ssl_opts => {
         SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
         verify_hostname => 0,
      }
   );
   my $response = $Browser->post(
      "https://$public_ip/install.php",
      [
         'sitename' => 'FullAuto',
         'fancy' => 'enable',
         'ssl' => 'always',
         'host' => 'localhost',
         'dbtype' => 'mysql',
         'database' => 'gnusocial',
         'dbusername' => 'gnusocial',
         'dbpassword' => 'goodrandompassword',
         'admin_nickname' => 'admin',
         'admin_password' => 'admin',
         'admin_password2' => 'admin',
         'admin_email' => $verified_email,
         'site_profile' => 'public',
         'submit' => 'Submit',
      ],
   );
   print $response->content;    
   my $starting_gnusocial=<<'END';



     .oPYo. ooooo    .oo  .oPYo. ooooo o o    o .oPYo.      o    o  .oPYo.
     8        8     .P 8  8   `8   8   8 8b   8 8    8      8    8  8    8
     `Yooo.   8    .P  8  8YooP'   8   8 8`b  8 8           8    8  8YooP'
         `8   8   oPooo8  8   `b   8   8 8 `b 8 8   oo      8    8  8
          8   8  .P    8  8    8   8   8 8  `b8 8    8      8    8  8
     `YooP'   8 .P     8  8    8   8   8 8   `8 `YooP8      `YooP'  8
     ....................................................................
     ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
     ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


                           https://gnu.io/social/

                        ____ _   _ _   _     ____             _       _
        ,= ,-_-. =.    / ___| \ | | | | |   / ___|  ___   ___(_) __ _| |
       ((_/)o o(\_))  | |  _|  \| | | | |   \___ \ / _ \ / __| |/ _` | |
        `-'(. .)`-'   | |_| | |\  | |_| |    ___) | (_) | (__| | (_| | |
            \_/        \____|_| \_|\___/    |____/ \___/ \___|_|\__,_|_|


 (The Free Software Foundation is **NOT** a sponsor of the FullAuto© Project.)
END
   print $starting_gnusocial;sleep 10;
   $region=~s/^.*['](.*)[']$/$1/;
   ($stdout,$stderr)=$handle->cmd('sudo wget -qO- '.
      'http://docs.aws.amazon.com/ses/latest/DeveloperGuide/smtp-connect.html'
      );
   my @smtp_servers=();my $smtp_server='us-east-1';
   foreach my $line (split /\n/,$stdout) {
      if (-1<index $line,'email-smtp.') {
         $line=~s/^.*(email-smtp\.[^Hh].*?com).*$/$1/;
         next unless $line=~/^email-smtp/;
         push @smtp_servers,$line;
         if (-1<index $line,$region) {
            $smtp_server=$line;
            last;
         }
      }
   }
print "\nSMTP SERVER = $smtp_server and\nVERIFIED_EMAIL = $verified_email and\nSMTPPASS=$smtppass and\nID=$hash->{AccessKey}->{AccessKeyId}\n";
   print "\n   ACCESS GNU SOCIAL UI AT:\n\n",
         " https://$public_ip/index.php\n";
   my $thanks=<<'END';

     ______                  _    ,
       / /              /   ' )  /        /
    --/ /_  __.  ____  /_    /  / __ . . /
   (_/ / /_(_/|_/ / <_/ <_  (__/_(_)(_/_'   For Trying
                             //

           _   _      _         _____      _ _    _         _
          | \ | | ___| |_      |  ___|   _| | |  / \  _   _| |_  |
          |  \| |/ _ \ __| o o | |_ | | | | | | / _ \| | | | __/ | \
          | |\  |  __/ |_  o o |  _|| |_| | | |/ ___ \ |_| | ||     |
          |_| \_|\___|\__|     |_|   \__,_|_|_/_/   \_\__,_|\__\___/ ©


   Copyright © 2000-2016  Brian M. Kelly  Brian.Kelly@FullAuto.com

END
   eval {
      local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
      alarm 15;
      print $thanks;
      print "   \n   Press Any Key to EXIT ... ";
      <STDIN>;
   };alarm(0);
   print "\n\n\n   Please wait at least a minute for the Default Browser\n",
         "   to start with your new GNU Social installation!\n\n\n";
   &Net::FullAuto::FA_Core::cleanup;

};

my $standup_gnusocial=sub {

   my $type="]T[{select_type}";
   $type=~s/^"//;
   $type=~s/"$//;
   $type=substr($type,0,(index $type,' ->')-3);
   my $region="]T[{awsregions}";
   $region=~s/^"//;
   $region=~s/"$//;
   my $verified_email="]T[{pick_email}";
   if (-1<index $verified_email,'Enter ') {
      $verified_email="]I[{'gnusocial_enter_email_address',1}";
   }
   my $gnusocial="]T[{select_gnusocial_setup}";
   my $permanent_ip="]T[{permanent_ip}";
   my $i=$main::aws->{fullauto}->{ImageId}||'';
   my $s=$main::aws->{fullauto}->
         {NetworkInterfaces}->[0]->{SubnetId}||'';
   my $g=$main::aws->{fullauto}->
         {SecurityGroups}->[0]->{GroupId}||'';
   my $n=$main::aws->{fullauto}->
         {SecurityGroups}->[0]->{GroupName}||'';
   my $c='aws ec2 describe-security-groups '.
         "--group-names $n";
   my ($hash,$output,$error)=('','','');
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error;
   my $cidr=$hash->{SecurityGroups}->[0]->{IpPermissions}
            ->[0]->{IpRanges}->[0]->{CidrIp};
   $c='aws ec2 create-security-group --group-name '.
      'GNUSocialSecurityGroup --description '.
      '"GNU.io/Social Security Group" 2>&1';
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error
      && $error!~/already exists/;
   $c='aws ec2 authorize-security-group-ingress '.
      '--group-name GNUSocialSecurityGroup --protocol '.
      'tcp --port 22 --cidr '.$cidr." 2>&1";
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error
      && $error!~/already exists/;
   $c='aws ec2 authorize-security-group-ingress '.
      '--group-name GNUSocialSecurityGroup --protocol '.
      'tcp --port 80 --cidr '.$cidr." 2>&1";
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error
      && $error!~/already exists/;
   $c='aws ec2 authorize-security-group-ingress '.
      '--group-name GNUSocialSecurityGroup --protocol '.
      'tcp --port 443 --cidr '.$cidr." 2>&1";
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error
      && $error!~/already exists/;
   my $cnt=0;
   my $pemfile=$pem_file;
   $pemfile=~s/\.pem\s*$//s;
   if (exists $main::aws->{'GNU.io/Social'}) {
      my $g=get_aws_security_id('GNUSocialSecurityGroup');
      my $c="aws ec2 run-instances --image-id $i --count 1 ".
         "--instance-type $type --key-name $pemfile ".
         "--security-group-ids $g --subnet-id $s";
      if ($#{$main::aws->{'GNU.io/Social'}}==0) {
         launch_server('GNU.io/Social',$cnt,$gnusocial,'',$c,
         $configure_gnusocial,'',$region,$verified_email,
         $permanent_ip);
      } else {
         my $num=$#{$main::aws->{'GNU.io/Social'}}-1;
         foreach my $num (0..$num) {
            launch_server('GNU.io/Social',$cnt++,$gnusocial,'',$c,
            $configure_gnusocial,'',$region,$verified_email,
            $permanent_ip);
         }
      }
   }

   return '{choose_demo_setup}<';

};

my $gnusocial_setup_summary=sub {

   package gnusocial_setup_summary;
   use JSON::XS;
   my $region="]T[{awsregions}";
   $region=~s/^"//;
   $region=~s/"$//;
   my $type="]T[{select_type}";
   $type=~s/^"//;
   $type=~s/"$//;
   my $money=$type;
   $money=~s/^.*-> \$(.*?) +(?:[(].+[)] )*\s*per hour$/$1/;
   $type=substr($type,0,(index $type,' ->')-3);
   my $gnusocial="]T[{select_gnusocial_setup}";
   $gnusocial=~s/^"//;
   $gnusocial=~s/"$//;
   my $permanent_ip="]T[{permanent_ip}";
   if ($permanent_ip=~/^["]Release.* (\d+\.\d+\.\d+\.\d+).*$/s) {
      my $ip_to_release=$1;
      my $c="aws ec2 describe-addresses";
      my ($hash,$output,$error)=
         &Net::FullAuto::Cloud::fa_amazon::run_aws_cmd($c);
      $hash||={};$hash->{Addresses}||=[];
      foreach my $address (@{$hash->{Addresses}}) {
         if ($address->{PublicIp} eq $ip_to_release) {
            my $c="aws ec2 release-address ".
                  "--allocation-id $address->{AllocationId}";
            my ($hash,$output,$error)=
               &Net::FullAuto::Cloud::fa_amazon::run_aws_cmd($c);
            last;
         }
      }
      print "\n   $ip_to_release HAS BEEN RELEASED . . .\n";
      sleep 5;
   }
   my $num_of_servers=0;
   my $ol=$gnusocial;
   $ol=~s/^.*(\d+)\sServer.*$/$1/;
   if ($ol==1) {
      $main::aws->{'GNU.io/Social'}->[0]=[];
   } elsif ($ol=~/^\d+$/ && $ol) {
      foreach my $n (0..$ol) {
         $main::aws->{'GNU.io/Social'}=[] unless exists
            $main::aws->{'GNU.io/Social'};
         $main::aws->{'GNU.io/Social'}->[$n]=[];
      }
   }
   $num_of_servers=$ol;
   my $cost=int($num_of_servers)*$money;
   my $cents='';
   if ($cost=~/^0\./) {
      $cents=$cost;
      $cents=~s/^0\.//;
      if (length $cents>2) {
         $cents=~s/^(..)(.*)$/$1.$2/;
         $cents=~s/^0//;
         $cents=' ('.$cents.' cents)';
      } else {
         $cents=' ('.$cents.' cents)';
      }
   }
   my $show_cost_banner=<<'END';

      _                  _       ___        _  ___
     /_\  __ __ ___ _ __| |_    / __|___ __| ||__ \
    / _ \/ _/ _/ -_) '_ \  _|  | (__/ _ (_-<  _|/_/
   /_/ \_\__\__\___| .__/\__|   \___\___/__/\__(_)
                   |_|

END
   $show_cost_banner.=<<END;
   Note: There is a \$$cost per hour cost$cents to launch $num_of_servers
         AWS EC2 $type servers for the following application:

         $gnusocial


END
   my %show_cost=(

      Name => 'show_cost',
      Item_1 => {

         Text => "I accept the \$$cost$cents per hour cost",
         Result => $standup_gnusocial,

      },
      Item_2 => {

         Text => "Return to Choose Instruction Set Menu",
         Result => sub { return '{choose_demo_setup}<' },

      },
      Item_3 => {

         Text => "Exit FullAuto",
         Result => sub { Net::FullAuto::FA_Core::cleanup() },

      },
      Scroll => 1,
      Banner => $show_cost_banner,

   );
   return \%show_cost;

};

our $check_elastic_ip=sub {

   my $c="aws ec2 describe-addresses";
   my ($hash,$output,$error)=run_aws_cmd($c);
   $hash||={};$hash->{Addresses}||=[];
   if (-1==$#{$hash->{Addresses}}) {
      my $permanent_ip_banner=<<'END';
    ___                                 _     ___ ___ ___
   | _ \___ _ _ _ __  __ _ _ _  ___ _ _| |_  |_ _| _ \__ \
   |  _/ -_) '_| '  \/ _` | ' \/ -_) ' \  _|  | ||  _/ /_/
   |_| \___|_| |_|_|_\__,_|_||_\___|_||_\__| |___|_|  (_)
END
      $permanent_ip_banner.=<<END;

   If you plan on using this GNU Social server for an extended
   period, you will need a non-temporary IP Address. In Amazon
   Web Services, one Elastic IP (Amazon's way of allocating long 
   term IP addresses) is free so long as it is associated to
   a running server. If you stop or terminate the server, you
   need to manually release the address, or you will incur charges.

   Note also, that a Permanent IP Address will substantially
   increase the likelihood of email being sent from the GNU Social
   server surviving spam filters and actually arriving at the
   intended destination.

END
      my $permanent_ip={

         Name => 'permanent_ip',
         Item_1 => {

            Text => 'Use Elastic (Permanent) IP Address',
            Result => $gnusocial_setup_summary,

         },
         Item_2 => {

            Text => 'Stay with Temporary Public IP Address',
            Result => $gnusocial_setup_summary,

         },
         Scroll => 2,
         Result => $gnusocial_setup_summary,
         Banner => $permanent_ip_banner,

      };
      return $permanent_ip;
   } else {
      my $c="aws ec2 describe-instances";
      my ($hash,$output,$error)=run_aws_cmd($c);
      $hash||={};$hash->{Addresses}||=[];
      my %pubip=();
      foreach my $res (@{$hash->{Reservations}}) {
         foreach my $inst (@{$res->{Instances}}) {
            my $pip=$inst->{PublicIpAddress}||'';
            next unless $pip;
            next if exists $inst->{State}->{Name} &&
               $inst->{State}->{Name} eq 'terminated';
            $pubip{$pip}='';
         }
      }
      $c="aws ec2 describe-addresses";
      ($hash,$output,$error)=run_aws_cmd($c);
      my @available=();my @available_remove=();
      foreach my $address (@{$hash->{Addresses}}) {
         unless (exists $pubip{$address->{PublicIp}}) {
            push @available, $address->{PublicIp};
            push @available_remove,"Release IP Address $address->{PublicIp}"; 
         }
      }
      if (-1<$#available) {
         my $use_elastic_banner=<<'END';
    _   _           ___ _         _   _      ___ ___ ___ 
   | | | |___ ___  | __| |__ _ __| |_(_)__  |_ _| _ \__ \ 
   | |_| (_-</ -_) | _|| / _` (_-<  _| / _|  | ||  _/ /_/
    \___//__/\___| |___|_\__,_/__/\__|_\__| |___|_|  (_)
END
         $use_elastic_banner.=<<END;

   An allocated but not associated Elastic IP has been identified.
   Using this IP Address for GNU Social may avoid charges from
   Amazon that are levied against allocated but not associated
   Elastic IPs. Please make a selection.

END
         my $permanent_ip={

            Name => 'permanent_ip',
            Item_1 => {

               Text => "Use Elastic (Permanent) IP Address ]C[",
               Convey => \@available,
               Result => $gnusocial_setup_summary,

            },
            Item_2 => {

               Text => "Stay with Temporary Public IP Address &\n".
                       "                 ]C[ (to avoid cost)",
               Convey => \@available_remove,
               Result => $gnusocial_setup_summary,

            },
            Item_3 => {

               Text => 'Stay with Temporary Public IP Address',
               Result => $gnusocial_setup_summary,

            },
            Scroll => 3,
            Result => $gnusocial_setup_summary,
            Banner => $use_elastic_banner,

         };
         return $permanent_ip;
      } else {
         my $new_elastic_banner=<<'END';
    _  _              ___ _         _   _      ___ ___ ___
   | \| |_____ __ __ | __| |__ _ __| |_(_)__  |_ _| _ \__ \
   | .` / -_) V  V / | _|| / _` (_-<  _| / _|  | ||  _/ /_/
   |_|\_\___|\_/\_/  |___|_\__,_/__/\__|_\__| |___|_|  (_)
END
         $new_elastic_banner.=<<END;

   Allocated Elastic IP Addresses have been identified, but
   all are currently associated with server instances. A new
   one can be allocated and associated with your new GNU
   Social server, but an additional cost of \$0.005 (half cent)
   per hour will be incurred. Please make a selection.

END
         my $permanent_ip={

            Name => 'permanent_ip',
            Item_1 => {

               Text => 'Allocate Additional Elastic (Permanent) IP Address',
               Result => $gnusocial_setup_summary,

            },
            Item_2 => {

               Text => 'Stay with Temporary Public IP Address',
               Result => $gnusocial_setup_summary,

            },
            Scroll => 2,
            Result => $gnusocial_setup_summary,
            Banner => $new_elastic_banner,

         };
         return $permanent_ip;
      }
   }

};

our $gnusocial_validate_email=sub {

   my $email="]I[{'gnusocial_enter_email_address',1}";
   my $confirm="]I[{'gnusocial_enter_email_address',2}";
   unless ($email eq $confirm) {
      STDOUT->autoflush(1);
      print "\n   ERROR: Email Addresses do not match!";sleep 5;
      STDOUT->autoflush(0);
      return '<';
   } elsif ($email=~/^\s*$/) {
      STDOUT->autoflush(1);
      print "\n   ERROR: You failed to enter an Email Address!";sleep 5;
      STDOUT->autoflush(0);
      return '<';
   } elsif ($email!~/\@/) {
      STDOUT->autoflush(1);
      print "\n   ERROR: Email Address must contain \'\@\' character!";sleep 5;
      STDOUT->autoflush(0);
      return '<';
   }
   my $c="aws ses verify-email-identity --email-address $email";
   my ($hash,$output,$error)=run_aws_cmd($c);
   my $inform_banner=<<'END';

    ___                     _            _   _
   |_ _|_ __  _ __  ___ _ _| |_ __ _ _ _| |_| |
    | || '  \| '_ \/ _ \ '_|  _/ _` | ' \  _|_|
   |___|_|_|_| .__/\___/_|  \__\__,_|_||_\__(_)
             |_|

END
   $inform_banner.=<<END;
   The email address you just entered: $email

   has been submitted to Amazon Web Services for verification. Amazon
   will be sending an email to this address that you must respond to
   in order for this address to work with your GNU Social installation.
   You can take a few minutes to do this now, or after you complete this
   installation. Just note, that email in you GNU Social server will
   not work until you have responded to Amazon's email.

END
   my $email_message={

      Name => 'email_message',
      Result => $check_elastic_ip,
      Banner => $inform_banner,

   };
   return $email_message;

};

our $gnusocial_enter_email_address=sub {

   my $gnusocial_email_banner=<<'END';

    ___     _             ___            _ _     _      _    _
   | __|_ _| |_ ___ _ _  | __|_ __  __ _(_) |   /_\  __| |__| |_ _ ___ ______
   | _|| ' \  _/ -_) '_| | _|| '  \/ _` | | |  / _ \/ _` / _` | '_/ -_|_-<_-<
   |___|_||_\__\___|_|   |___|_|_|_\__,_|_|_| /_/ \_\__,_\__,_|_| \___/__/__/

END
   $gnusocial_email_banner.=<<END;

   Type or Copy & Paste the main contact email for GNU Social here:

   (Use [TAB] key to switch between input boxes)


   Email Address
                    ]I[{1,'',50}

   Confirm Address
                    ]I[{2,'',50}


END

   my $gnusocial_enter_email_address={

      Name => 'gnusocial_enter_email_address',
      Input => 1,
      Result => $gnusocial_validate_email,
      #Result => $gnusocial_setup_summary,
      Banner => $gnusocial_email_banner,

   };
   return $gnusocial_enter_email_address;

};

our $gnusocial_pick_email_address=sub {

   package gnusocial_pick_email_address;
   use Net::FullAuto::Cloud::fa_amazon;
   my $c="aws ses list-identities";
   my ($hash,$output,$error)=run_aws_cmd($c);
   my @identities=grep { /\@/ } @{$hash->{Identities}};
   if (-1<$#identities) {

      my $pick_banner=<<'END';

    ___ _    _     ___            _ _     _      _    _
   | _ (_)__| |__ | __|_ __  __ _(_) |   /_\  __| |__| |_ _ ___ ______
   |  _/ / _| / / | _|| '  \/ _` | | |  / _ \/ _` / _` | '_/ -_|_-<_-<
   |_| |_\__|_\_\ |___|_|_|_\__,_|_|_| /_/ \_\__,_\__,_|_| \___/__/__/
END
      $pick_banner.=<<'END';

   In order for email functionality to work with GNU Social, you need to
   associate an Amazon Web Services verified email address. The following
   email addresses have been identified as verifed Amazon addresses. Please
   select one, or choose to create a new one. Note that if you choose to
   create a new one, it will have to be verified before email functionality
   in GNU Social will work properly. This setup wizard will notify Amazon,
   and Amazon will send an email to the entered address. You must respond to
   that email in order to complete verification. You can also verify
   addresses manually at this Amazon URL:

http://docs.aws.amazon.com/ses/latest/DeveloperGuide/verify-email-addresses.html

END
      my $pick_email={
      
         Name => 'pick_email',
         Item_1 => {

            Text => "Enter and verify a different address\n\n",
            Result =>
      $Net::FullAuto::ISets::Amazon::GNUSocial_is::gnusocial_enter_email_address->(),

         },
         Item_2 => {

            Text => "]C[",
            Convey => \@identities,
            Result => $check_elastic_ip,

         },
         Scroll => 2,
         Banner => $pick_banner,
      };
      return $pick_email;
   } else {
      $Net::FullAuto::ISets::Amazon::GNUSocial_is::gnusocial_enter_email_address->();
   }

};

our $select_gnusocial_setup=sub {

   my @options=('GNU Social & MySQL & NGINX on 1 Server');
   my $gnusocial_setup_banner=<<'END';

  
                          https://gnu.io/social/

                        ____ _   _ _   _     ____             _       _
        ,= ,-_-. =.    / ___| \ | | | | |   / ___|  ___   ___(_) __ _| |
       ((_/)o o(\_))  | |  _|  \| | | | |   \___ \ / _ \ / __| |/ _` | |
        `-'(. .)`-'   | |_| | |\  | |_| |    ___) | (_) | (__| | (_| | |
            \_/        \____|_| \_|\___/    |____/ \___/ \___|_|\__,_|_|


   Choose the GNU Social setup you wish to set up. Note that more or larger
   capactiy servers means more expense. Consider a medium or large instance
   type (previous screens) if you foresee a lot of traffic on the server. You
   can navigate backwards and make new selections with the [<] LEFTARROW key.

END
   my %select_gnusocial_setup=(

      Name => 'select_gnusocial_setup',
      Item_1 => {

         Text => ']C[',
         Convey => \@options,
         Result => $gnusocial_pick_email_address,

      },
      Scroll => 1,
      Banner => $gnusocial_setup_banner,
   );
   return \%select_gnusocial_setup

};

1
