#!/usr/bin/perl

use 5.24.0;
use strict;
use warnings;
use Carp qw/croak/;
use YAML qw(LoadFile);
use Data::Dumper qw(Dumper);
use Cwd qw(cwd);
use File::Path;
use File::Copy;

# my $data = LoadFile("printers.yml");

my $printers = LoadFile("printers.yml");
print Dumper $printers;
my $models = LoadFile("models.yml");
print Dumper $models;

# TODO use sudo or root?
# # test

sub get_description {
    my ($printer_name) = @_;
    return "$printer_name (FI MUNI)"
}

sub prompt_username {
    print "Enter username: ";
    chomp(my $username = <STDIN>);
    return $username
}

sub prompt_password {
    print "Enter password: ";
    system("stty -echo");
    chomp(my $password1 = <STDIN>);
    system('stty echo');
    print "\nRepeat password: ";
    system('stty -echo');
    chomp(my $password2 = <STDIN>);
    system("stty echo");
    print "\n";
    if ($password1 ne $password2) {
        say "Error: Passwords do not match!";
        exit 1;
    }
    return $password1
}

sub get_url {
    my ($printer_name) = @_;
    my $user = prompt_username();
    my $password = prompt_password();

    return "smb://NTFI\\${user}:${password}\@print.fi.muni.cz/$printer_name"

}

sub hp_laserjet_600 {
    my ($printer_name) = @_;

    # if ($? != 0) {
    #     die "Could not make folder";
    # }

    # my $dir = cwd;
    # say $dir;
    my $url = get_url($printer_name);

    my $command = qq(lpadmin \\
    -p "${printer_name}.fi.muni" \\
    -D "${printer_name} (FI MUNI)" \\
    -L "$printers->{$printer_name}->{'location'}" \\
    -E \\
    -v "${url}" \\
    -P "ppds/${printer_name}.ppd" \\
    -o media-default=iso_a4_210x297mm \\
    -o sides-default=two-sided-long-edge \\
    -o auth-info-required=username,password \\
           -o HPOption_Duplexer=True); # REVIEW nevím jestli tohle je ok

    say $command;

    system($command);
}

sub TA_4505ci {
    my ($printer_name) = @_;
    my $url = get_url($printer_name);
    
    # Add cups printer
    # sudo lpadmin                              CLI CUPS administration
    # -p "${printers[$printer]}"                Set printer name
    # -D "${descriptions[$printer]}"            Set printer description
    # -L "${locations[$printer]}"               Set printer location
    # -E                                        Enables the destination and accepts jobs (cupsaccept+cupsenable)
    # -v smb://print.fi.muni.cz/$printer        Set printer URI
    # -m UTAX_TA/TA4505ci.ppd                   Set PPD file
    # -o media-default=iso_a4_210x297mm         Set default paper format
    # -o sides-default=two-sided-long-edge      Set two-sided as default
    # -o auth-info-required=username,password   Enable password authentication
    # -o Option19=One                           Cassettes 3, 4 installed
    # -o Option21=True                          Punch unit installed
    # -o Option17=DF730                         1000-page finisher installed

    my $command = qq(lpadmin \\
    -p "${printer_name}.fi.muni" \\
    -D "${printer_name} (FI MUNI)" \\
    -L "$printers->{$printer_name}->{'location'}" \\
    -E \\
    -v "${url}" \\
    -P "ppds/${printer_name}.ppd" \\
    -o media-default=iso_a4_210x297mm \\
    -o sides-default=two-sided-long-edge \\
    -o auth-info-required=username,password \\
    -o Option19=One \\
    -o Option21=True \\
    -o Option17=DF730); 

    say $command;

    system($command);
}

sub generic_printer {
    my ($printer_name) = @_;
    my $url = get_url($printer_name);

    my $command = qq(lpadmin \\
    -p "${printer_name}.fi.muni" \\
    -D "${printer_name} (FI MUNI)" \\
    -L "$printers->{$printer_name}->{'location'}" \\
    -E \\
    -v "${url}" \\
    -P "ppds/${printer_name}.ppd" \\
    -o media-default=iso_a4_210x297mm \\
    -o sides-default=two-sided-long-edge \\
    -o auth-info-required=username,password); 

    say $command;

    system($command);
    
}

sub copy_filter {
    (my $filter) = @_;
    # my $filter = "kyofilter_B";
    my $destination = "/usr/libexec/cups/filter/";
    $destination = "first/second/";

    if (! -d $destination) {
        my $dirs = eval {mkpath($destination)};
        die "Failed to create $destination $@\n" unless $dirs;
    }
    
    copy($filter, $destination)
        or die "Failed to copy $filter: $!\n";
    say "[OK] Copied $filter."
    
   
}


sub print_printers() {
    say "Available printers:";
    printf "%-14s | %s\n", "Printer name", "Location";
    say "-"x50;
    for(sort keys %$printers) {
        printf "%-14s | %s\n", $_, $printers->{$_}->{location};
    }
}

sub usage() {
    say "Script to install FI printers on linux. ";
    say "Requires local CUPS server running and SAMBA client installed.";
    say "usage: $0 <printer-name>";
    say "Triumph-Adler 50007ci needs Python 2.7 as a dependency.";
    print "\n\n";
    print_printers();
    #foreach my $key (keys %$printers)
    #{
    #    print "$key ";
    #}
    #print "\n";

    exit 1;
}

sub check_python {
    my $regex = /^Python 2\.7*/; #FIXME Use of unitialized value $_ in pattern match
    my $output = qx/python -V 2>&1/;
    if ($output =~ $regex) {
        say "[OK] Python 2.7 is present.";
        return "python ";
    }
    else {
        # TODO FIXME ADD python2
        say "[ERROR] Python 2.7 is not present";
        # TRY python2 command
        my $s_output = qx/python2 -V 2>&1/;
        if ($s_output =~ $regex) {
            say "ASI OK, TESTING NEEDED"; # TODO OTESTOVAT
            return "python2 ";
        }
        else {
            die "Python 2.7 Not Found and is needed for TA5007ci\n";
        }
    }
}

my $printer_name = shift or usage();

my $output=`which smbclient >/dev/null 2>/dev/null`;
my $status=$?;
say $status;
say $output;
# TODO enable this
if ($? != 0) {
    say "Samba client seems not to be installed. (smbclinet)";
    exit 1;
}

if (not (exists($printers->{$printer_name}))) {
    say "Printer $printer_name is not supported.";
    print_printers();
    exit 1;
}


#if ($<) {
#    say "This program is meant to be run as a root";
#    say
#    die "Error: exiting program as not executed by root\n";
#}

sub python_package {
    (my $package, my $python) = @_;
    
    say "[INFO] Installing $package";
    my $status = chdir "$package";
    if ($status == 0) {
        say "[ERROR] folder $package is not present";
    }
    my $output = system("${python} setup.py install");
    if ($? != 0) {
        die "[ERROR] $package exited with different exit code than 0!";
    }
    $status = chdir '..';
    if ($status == 0) {
        die "[FATAL] Could not return to the working directory";
    }
    
}

sub pre_TA5007ci {
    my $python = check_python;
    python_package "PyPDF2-1.26.0", $python;
    python_package "reportlab", $python;
}

say $printers->{$printer_name}->{'model'};
my $model = $printers->{$printer_name}->{'model'};



if ($model eq "TA5007ci") {
    pre_TA5007ci();
}


if ($model eq "TA4505ci") {
    TA_4505ci "$printer_name";
}
elsif ($model eq "hp-laserjet-600") {
    hp_laserjet_600 $printer_name;
}
else {
    generic_printer("$printer_name");
}
  
# NOTE there was a problem before //  THIS DOESNT WORK?
foreach ($models->{$model}->{'filters'}) {
    foreach(@$_){
        say $_;
    }
} 

say "DONE!";
# hp_laserjet_600($printer_name);

