#!/usr/bin/perl
# ---------------------------------------------------------------
# Prontus CMS
# http://www.prontus.cl
# by Altavoz.net
#
# licensed under LGPL license.
# http://www.prontus.cl/license.html
# ---------------------------------------------------------------
# PROPOSITO
# ---------------------------------------------------------------
# Subir archivos desde el FID.
# ---------------------------------------------------------------
use strict;
use utf8;

BEGIN {
    use FindBin qw($Bin);
    my $pathLibsProntus = $Bin;
    unshift(@INC,$pathLibsProntus);
}

END {
    &tareas_salida();
}

# Captura STDERR
use lib_stdlog;
&lib_stdlog::set_stdlog($0, 51200);

use JSON;
use prontus_varglb; &prontus_varglb::init();
use glib_fildir_03;
use lib_prontus;
use Artic;
use lib_thumb;
use lib_waitlock;
use lib_upload;

my $LOCK = '';
my $LOCKFH;
my $ID = '';

main: {
    &lib_prontus::setUtf8();

    if (scalar @ARGV < 2) {
        print STDERR "Intento de invocación sin los parámetros indispensables.\n";
        print "Uso: perl $0 {prontus_id} {file_path} {ts}\n";
        exit;
    }

    $prontus_varglb::PRONTUS_ID = $ARGV[0];
    my $file  = $ARGV[1];
    my $ts = '';
    $ts = $ARGV[2] if (defined($ARGV[2]));

    my $msg_load = &lib_prontus::load_config_by_id($prontus_varglb::PRONTUS_ID);
    if ($msg_load ne '') {
        print STDERR "Ha ocurrido un error: $msg_load\n";
        exit;
    }

    # Agregar archivos al articulo.
    my $galeriaproc = "$prontus_varglb::DIR_SERVER/$prontus_varglb::PRONTUS_ID/cpan/procs/galeria";
    &glib_fildir_03::check_dir($galeriaproc);

    $file =~ /\/(\w+)\.\w+$/;
    $ID = $1;

    &write_json_result(1, "Procesando", 0);

    &lib_upload::clean_zip_folder($ts);

    &valida_invocacion($file, $ts);

    if ($ts ne '') {
        $LOCK = "$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_LOCKS'}/$ts.mutex";
        $LOCKFH = &lib_waitlock::lock_file($LOCK);
    }

    &upload_fotos_zip($file, $ts);
}

sub upload_fotos_zip {
    my $file = $_[0];
    my $ts = $_[1];
    if ($file =~ /[^\/\\]+?\.zip$/i) {
        my $time = time;

        # Agregar archivos al articulo.
        my $galeriaproc = "$prontus_varglb::DIR_SERVER/$prontus_varglb::PRONTUS_ID/cpan/procs/galeria";
        my $outputdir = "$galeriaproc/$ts/$time";
        $outputdir = "$galeriaproc/$time" if ($ts eq '');

        &glib_fildir_03::check_dir($outputdir);

        my $unzip = `unzip -oj $file -d $outputdir`;
        my @fotos = glob("$outputdir/*");
        unlink $file;

        if (scalar @fotos > 0) {
            my @fotos_agregadas;
            my @fotos_descartadas; # si una foto no es válida, la agrego acá para notificar.

            my $artic_obj;
            if ($ts ne '') {
                unless($artic_obj = Artic->new(
                            'document_root'         => $prontus_varglb::DIR_SERVER,
                            'prontus_id'            => $prontus_varglb::PRONTUS_ID,
                            'public_server_name'    => $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PUBLIC_SERVER_NAME'},
                            'cpan_server_name'      => $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'CPAN_SERVER_NAME'},
                            'ts'                    => $ts,
                            'campos'                => {})) {

                    print STDERR "[error] Error inicializando objeto articulo: $Artic::ERR\n";
                    &write_json_result(0, "[error] Error inicializando objeto articulo: $Artic::ERR");
                }
            }

            foreach my $foto (@fotos) {
                if ($foto =~ /([^\/\\]+?)\.(\w+)$/) {
                    # print STDERR "foto[$foto]\n";
                    my $nombre_foto = $1;
                    my $ext = lc $2;
                    my $foto_rel = $foto;

                    if ($ext !~ /(jpg|jpeg|png|gif|svg|webp)$/i) {
                        print STDERR "Extension no válida: [$foto]\n";
                        push @fotos_descartadas, &lib_prontus::strip_text($nombre_foto) . '.' . &lib_prontus::strip_text($ext);
                        next;
                    }

                    if (! &lib_thumb::get_tipo($foto_rel)) {
                        push @fotos_descartadas, &lib_prontus::strip_text($nombre_foto) . '.' . &lib_prontus::strip_text($ext);
                        next;
                    }

                    $foto_rel =~ s/$prontus_varglb::DIR_SERVER//sg;
                    $nombre_foto = &lib_prontus::strip_text($nombre_foto);

                    my ($msg_size, $wfoto, $hfoto, $orientation) = &lib_prontus::dev_tam_img($foto);
                    my $img_type = &lib_thumb::get_imag_extension($foto);

                    if (&lib_prontus::can_edit_img($img_type)) {
                        # corrige la rotacion de la imagen de acuerdo al exif
                        if ($img_type eq 'jpg' && $orientation > 1) {
                            my $binfoto = &lib_thumb::apply_orientation_jpg($foto, $orientation);
                            &lib_thumb::write_image($foto, $binfoto);
                        }
                        # Redimensiona la foto al limite establecido si es que lo supera.
                        if ($prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'FOTO_MAX_PIXEL'} ne '') { # si no está vacio se reduce calidad de jpg, si corresponde.
                            my ($wmax, $hmax) = split("x", $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'FOTO_MAX_PIXEL'});
                            if ($wfoto > $wmax || $hfoto > $hmax) {
                                my ($wnew, $hnew) = &lib_thumb::calcular_proporcion_img($wfoto, $hfoto, $wmax, $hmax);
                                my ($binfoto, $wfoto, $hfoto) = &lib_thumb::make_resize($wnew, $hnew, $foto);
                                # si es gif , se genera png
                                if ($foto =~ /\.gif$/i) {
                                    unlink $foto; # se borra la foto original.
                                    $foto =~ s/\.gif$/\.png/i;
                                    $foto_rel =~ s/\.gif$/\.png/i;
                                    $ext = "png";
                                }
                                &lib_thumb::write_image($foto, $binfoto) if ($binfoto);
                            }
                        } elsif ($img_type eq 'jpg' && $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'REDUCIR_CALIDAD_JPEGS'} eq 'SI') {
                            # Si es un JPEG, y está habilitada la reducción de calidad de las imágenes, lo guardamos con la calidad especificada en prontus_varglb::NIVEL_OPTIMIZACION_JPG.
                            my ($ancho, $alto, $ratio) = &lib_thumb::get_propiedades($foto);
                            my ($binfoto, $wfoto, $hfoto) = &lib_thumb::make_resize($ancho, $alto, $foto);
                            # Se reemplaza el path por el de la foto redimensionada. Si el redimensionado fue exitoso
                            if ($binfoto) {
                                # se borra la foto original.
                                unlink $foto;
                                # se reemplaza con la foto "optimizada"
                                &lib_thumb::write_image($foto, $binfoto);
                            }
                        }
                    }

                    if ($ts eq '') {
                        push @fotos_agregadas, "$foto_rel;$nombre_foto.$ext";
                    } else {
                        # la foto cargada a traves de este metodo es original
                        my ($fotonum, $relpath_foto, $wfoto, $hfoto) = &lib_upload::agrega_foto_artic($foto_rel, "$nombre_foto.$ext", $artic_obj, 1);
                        $artic_obj->_flush_xml();

                        push @fotos_agregadas, "$relpath_foto;$fotonum;$wfoto;$hfoto";
                        unlink $foto;
                    }
                }
            }

            # si no es articulo nuevo borra directorio de descompresión
            if ($ts ne '') {
                glib_fildir_03::borra_dir($outputdir);
            }

            my $response;
            $response->{'status'} = 1;
            $response->{'msg'} = 'Zip procesado';
            $response->{'descartadas'} = \@fotos_descartadas;
            $response->{'aceptadas'} = \@fotos_agregadas;

            &write_json_result_hash($response);
        } else {
            glib_fildir_03::borra_dir("$galeriaproc/$ts") if ($ts ne '');
            glib_fildir_03::borra_dir("$galeriaproc/$time") if ($ts eq '');
            &write_json_result(0, "No fue posible descomprimir el archivo zip.");
        }

    } else {
        &write_json_result(0, "Nombre de archivo no es válido.");
    }
}

sub valida_invocacion {
    my ($file, $ts) = @_;

    if ($file eq '') {
        &write_json_result(0, "Archivo no especificado.");
    }

    # Se verifica el TS del articulo si viene
    if ($ts ne '') {
        if ($ts =~ /^(\d{8})\d{6}/) {
            my $xml_artic = "$prontus_varglb::DIR_SERVER$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_SITE'}/artic/$1/xml/$ts.xml";
            if (!-s $xml_artic) {
                print STDERR "Artículo no encontrado: TS no válido.[$xml_artic]\n";
                &write_json_result(0, "Artículo no encontrado: TS no es válido.");
            }
        } else {
            &write_json_result(0, "TS no es válido.");
        }
    }
}

sub write_json_result {
    my $status = $_[0];
    # mensaje
    my $msg    = $_[1];
    my $exit   = defined($_[2]) ? $_[2] : 1;

    my $resp;
    $resp->{'status'} = $status;
    $resp->{'msg'}    = $msg;

    my $json = encode_json($resp);
    utf8::decode($json);

    my $path = "$prontus_varglb::DIR_SERVER/$prontus_varglb::PRONTUS_ID/cpan/procs/galeria/$ID.json";
    &glib_fildir_03::write_file($path, $json);
    exit if ($exit);
}

sub write_json_result_hash {
    my $hash = $_[0];
    my $exit  = defined($_[1]) ? $_[1] : 1;

    my $json = encode_json($hash);
    utf8::decode($json);

    my $path = "$prontus_varglb::DIR_SERVER/$prontus_varglb::PRONTUS_ID/cpan/procs/galeria/$ID.json";
    &glib_fildir_03::write_file($path, $json);
    exit if ($exit);
}

sub tareas_salida {
    if ($LOCK ne '') {
        &lib_waitlock::unlock_file($LOCK, $LOCKFH);
    }
}
