package lib_profile;

use utf8;
use strict;
use warnings;

our %GROUPS = (
    'art_publish' => [
        'prontus_art_banco',
        'prontus_art_borrar',
        'prontus_art_check_url',
        'prontus_art_copy',
        'prontus_art_get_versions',
        'prontus_art_ficha',
        'prontus_art_quick_edit',
        'prontus_art_repair',
        'prontus_art_sbmit',
        'prontus_art_sbmit_ajax',
        'prontus_art_upload',
        'prontus_art_view_xml',
        'prontus_check_friendly',
        'prontus_buscar_relacionados',
        'prontus_urlf5_guardar',
        'prontus_urlf5_make_art_url',
        'prontus_dam_update_art',
        'prontus_editor_imag',
        'prontus_editor_imag_guardar',
        'prontus_audio_check',
        'prontus_audio_xcode',
        'prontus_audio_xcode_status',
        'prontus_qtfaststart_check',
        'prontus_videocut',
        'prontus_videogetsnapshot',
        'prontus_videoxcode',
        'prontus_videoxcodestatus',
        'prontus_s3_download',
        'prontus_s3_download_check',
        'facebook_posting',
        'twitter_posting',
        'youtube_posting',
        'mam_save',
        'mam_list',
        'mam_delete',
        '.editor_img', '.form_view' # grupos de grupos.
    ],
    'snp' => [
        'prontus_snp_admin',
        'prontus_snp_get_notif',
        'prontus_snp_send_artic_push',
        'prontus_snp_send_push'
    ],
    'seo' => [ # la configuración es parte de config.
        'prontus_seo_monitoreo',
        'prontus_seo_robots',
        'prontus_get_facebook_preview',
        'prontus_get_google_pagespeed',
        'prontus_get_google_preview',
        'prontus_get_google_stats',
        'prontus_port_seo_get',
        'prontus_port_seo_save',
        'prontus_schema_admin',
        'prontus_schema_save',
        'prontus_tax_seo',
        'prontus_tax_seo_save',
        'prontus_validar_robots',
    ],
    'elasticsearch' => [ # estadísticas de elasticsearch
        'prontus_admin_stats_es',
        'prontus_admin_get_stats_es',
        'prontus_admin_elasticsearch_reindex',
    ],
    'form_view' => [
        'prontus_form_download',
        'prontus_form_list',
    ],
    'form_delete' => [
        'prontus_form_delete'
    ],
    'art_list' => [
        'prontus_art_list',
        'prontus_port_art_list',
    ],
    'taxs' => [
        'prontus_tax_admin',
        'prontus_tax_borrar',
        'prontus_tax_export',
        'prontus_tax_guardar',
        'prontus_tax_guardarpos',
        'prontus_tax_import',
        'prontus_tax_mostrar',
        'prontus_urlf5_tax_ficha'
    ],
    'tags' => [
        'prontus_tags_admin',
        'prontus_tags_borrar',
        'prontus_tags_cambia_st',
        'prontus_tags_export',
        'prontus_tags_guardar',
        'prontus_tags_import',
        'prontus_tags_resumen',
        'prontus_tags_search',
        'prontus_urlf5_tag_ficha'
    ],
    'multitag' => [
        'prontus_multitag_admin',
        'prontus_multitag_export',
        'prontus_multitag_genera_select',
        'prontus_multitag_import',
        'prontus_multitag_limpia_cache',
        'prontus_multitag_load_data',
        'prontus_multitag_mant_borrar',
        'prontus_multitag_mant_guardar',
        'prontus_multitag_mant_limpia_cache'
    ],
    'ports' => [
        'prontus_port_admin',
        'prontus_port_art_list',
        'prontus_cfg_get',
        'prontus_port_borra_busqueda',
        'prontus_port_carga_busquedas',
        'prontus_port_check_md5sum',
        'prontus_port_guardar',
        'prontus_port_preview'
    ],
    'pltport' => [
        'prontus_pltport_borrar',
        'prontus_pltport_duplicar',
        'prontus_pltport_intercambiar',
        'prontus_port_get_versions',
    ],
    'urlf5' => [
        'prontus_urlf5_admin',
        'prontus_urlf5_borrar',
        'prontus_urlf5_guardar',
        'prontus_urlf5_import',
        'prontus_urlf5_get_list',
        'prontus_urlf5_make_art_url',
        'prontus_urlf5_tax_ficha',
        'prontus_urlf5_tax_ficha',
    ],
    'config' => [
        'prontus_admin_conf_art',
        'prontus_admin_conf_bd',
        'prontus_admin_conf_buscador',
        'prontus_admin_conf_cache',
        'prontus_admin_conf_cloudflare',
        'prontus_admin_conf_dropbox',
        'prontus_admin_conf_elasticsearch',
        'prontus_admin_conf_list',
        'prontus_admin_conf_port',
        'prontus_admin_conf_redes',
        'prontus_admin_conf_sitemap',
        'prontus_admin_conf_tag',
        'prontus_admin_conf_tax',
        'prontus_admin_conf_usr',
        'prontus_admin_conf_var',
        'prontus_admin_conf_xcoding',
        'prontus_admin_conf_pplayer',
        'prontus_admin_conf_oidc',
        'prontus_admin_conf_snp',
        'prontus_xcoding_getformatos',
        'prontus_xcoding_guardarformatos',
        'prontus_admin_conf_seo',
        'prontus_cfg_save',
        'prontus_get_youtube_tokens',
    ],
    'system' => [
        'prontus_admin_crons',
        'prontus_admin_plataforma',
        'prontus_admin_logs',
        'prontus_admin_get_log',
        'prontus_admin_get_stats_es',
        'prontus_alert_save',
    ],
    'maintenance' => [
        'prontus_art_regen',
        'prontus_admin_regen',
        'prontus_dam_regen',
        'prontus_admin_bd',
        'prontus_set_bd',
        'prontus_regenerabd',
        'prontus_admin_reindex',
        'prontus_indexer_webstart',
        'prontus_admin_purge',
        'prontus_admin_reindex',
        'prontus_admin_elasticsearch_reindex',
        'prontus_admin_stats_es',
        'prontus_cloudflare_purge',
        'prontus_admin_calendar',
        'prontus_port_regen',
        'prontus_regenera_taxport_web',
        'prontus_regenera_tagport_web',
        'prontus_regen_check_process',
        'prontus_update_calendar',
        'prontus_update',
    ],
    'users' => [
        'prontus_usr_admin',
        'prontus_usr_borrar',
        'prontus_usr_chgpass_sbmit',
        'prontus_usr_ficha',
        'prontus_usr_sbmit',
        'prontus_usr_list'
        # '.profile'
    ],
    'profile' => [
        'prontus_profile_admin',
        'prontus_profile_borrar',
        'prontus_profile_ficha',
        'prontus_profile_sbmit'
    ],
    'editor' => [
        'prontus_edit_borrar',
        'prontus_edit_copy',
        'prontus_edit_file',
        'prontus_edit_guardar',
        'prontus_edit_main',
        'prontus_edit_upload',
        'prontus_list_tree',
    ],
    'multimedia' => [
        'prontus_dam_search',
        'prontus_dam_asset_list',
        'prontus_dam_regen'
    ],
    'plugins' => [
        'prontus_admin_plugins'
    ],
    'edics' => [
        'prontus_edi_borrar',
        'prontus_edi_guardar',
        'prontus_edi_toggle_vigencia'
    ],
    'fid_editor' => [
        'prontus_fid_admin',
        'prontus_fid_guardar',
        'prontus_fid_get_config',
        'prontus_fid_guardar_json',
        'prontus_fid_guardar_plantilla',
    ],
    's3_explorer' => [
        'prontus_s3_browser',
        'prontus_s3_delete',
        'prontus_s3_list'
    ],
    # estando vacio no hay restriccion x cgi, es solo un permiso.
    'art_view_all' => [],
    'art_edit_others' => [],
    'art_view_others' => [],
    'art_alta' => [],
    'art_index' => [],
    'port_view_all' => [],
    'ports_vobo' => [],
    'ports_art_vobo' => [],
    'editor_img' => [],
    'manage' => [ # conjunto de grupos
        '.config', '.system', '.maintenance', '.urlf5'
    ],
    'category' => [ # conjunto de grupos
        '.taxs', '.tags', '.multitag'
    ],
    'cms_publish' => [
        '.snp', '.art_list', '.ports', '.category'
    ],
);

# hash usado para armar la ficha de edición de perfil
our @GROUP_DESCRIPTORS = (
    {'meta' => 'group_art_publish', 'label' => "Artículos: Publicar artículos", 'access' => 'cms_publish,art_publish,art_list'},
    {'meta' => 'group_art_alta', 'label' => "Artículos: Modificar Alta de artículos", 'access' => 'art_alta'},
    {'meta' => 'group_art_index', 'label' => "Artículos: Cambiar opciones de indexación", 'access' => 'art_index'},
    {'meta' => 'group_art_edit_others', 'label' => "Artículos: Editar de artículos de otros usuarios", 'access' => 'art_edit_others'},
    {'meta' => 'group_art_view_others', 'label' => "Artículos: Ver artículos de otros usuarios", 'access' => 'art_view_others'},
    {'meta' => 'group_art_view_all', 'label' => "Artículos: Ver todos los tipos de artículos", 'access' => 'art_view_all'},
    {'meta' => 'group_prontus_form_view', 'label' => "Artículos: Ver y descargar datos de Prontus Form", 'access' => 'form_view'},
    {'meta' => 'group_prontus_form_delete', 'label' => "Artículos: Borrar datos de Prontus Form", 'access' => 'form_delete'},
    {'meta' => 'group_port_edit', 'label' => "Portadas: Ver y Editar", 'access' => 'cms_publish,ports'},
    {'meta' => 'group_edics', 'label' => "Portadas: Administrador de ediciones", 'access' => 'edics'},
    {'meta' => 'group_pltport', 'label' => "Portadas: Administrar plantillas de portadas", 'access' => 'pltport'},
    {'meta' => 'group_port_publish', 'label' => "Portadas: Publicar/despublicar portadas", 'access' => 'ports_vobo'},
    {'meta' => 'group_port_publish_art', 'label' => "Portadas: Editar visibilidad de artículos publicados", 'access' => 'ports_art_vobo'},
    {'meta' => 'group_port_view_all', 'label' => "Portadas: Ver todas las portadas", 'access' => 'port_view_all'},
    {'meta' => 'group_tax_publish', 'label' => "Categorías: Ver y Editar", 'access' => 'cms_publish,category,taxs'},
    {'meta' => 'group_tag_publish', 'label' => "Tags: Ver y Editar", 'access' => 'cms_publish,category,tags'},
    {'meta' => 'group_multitag_publish', 'label' => "Tags Jerárquicos: Ver y Editar", 'access' => 'cms_publish,category,multitag'},
    {'meta' => 'group_seo', 'label' => "Administración de SEO", 'access' => 'seo'},
    {'meta' => 'group_admin_config', 'label' => "Administración: Configuración del CMS", 'access' => 'manage,config'},
    {'meta' => 'group_admin_maintenance', 'label' => "Administración: Mantenimiento del CMS", 'access' => 'manage,maintenance'},
    {'meta' => 'group_admin_system', 'label' => "Administración: Operaciones de sistema", 'access' => 'manage,system'},
    {'meta' => 'group_admin_fid_editor', 'label' => "Administración: Editor de FIDs", 'access' => 'manage,fid_editor'},
    {'meta' => 'group_admin_urlf5', 'label' => "Administración: Administrador de URLs", 'access' => 'manage,urlf5'},
    {'meta' => 'group_admin_s3', 'label' => "Administración: Explorar almacenamiento S3", 'access' => 'manage,s3_explorer'},
    {'meta' => 'group_admin_users', 'label' => "Administración: Cuentas de Usuario", 'access' => 'manage,users'},
    {'meta' => 'group_admin_profiles', 'label' => "Administración: Perfiles de Usuario", 'access' => 'manage,profile'},
    {'meta' => 'group_multimedia', 'label' => "Multimedia", 'access' => 'multimedia'},
    {'meta' => 'group_editor', 'label' => "Editor de archivos", 'access' => 'editor'},
    {'meta' => 'group_plugins', 'label' => "Plugins: Permitir el uso", 'access' => 'plugins'},
    {'meta' => 'group_snp', 'label' => "Notificaciones PUSH", 'access' => 'cms_publish,snp'}
);

# carga información de perfiles en variables globales.
sub load_profiles {
    my $profile = $_[0] || '';
    my %profiles = get_profiles($profile);

    foreach my $profile_id (keys %profiles) {
        $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PROFILES'}{$profile_id}{'name'} = $profiles{$profile_id}{'nombre'};
        $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PROFILES'}{$profile_id}{'description'} = $profiles{$profile_id}{'descripcion'};
        $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PROFILES'}{$profile_id}{'groups'} = $profiles{$profile_id}{'permisos'};
   }
}

# devuelve el listado de perfiles en bd
sub get_profiles {
    my $profile_id = $_[0];
    my $sql = "select PROFILES_ID, PROFILES_NOM, PROFILES_DESC, PROFILES_PERMISSIONS from PROFILES";
    my @params;
    if ($profile_id) {
        $sql .= " where PROFILES_ID = ?";
        @params = ($profile_id);
    }
    my ($perfil_id, $nombre, $descripcion, $permisos);
    my ($bd, $msg_err_bd) = lib_prontus::conectar_user_bd();
    my $salida = glib_dbi_03::ejecutar_sql_bind_param($bd, $sql, \@params, \($perfil_id, $nombre, $descripcion, $permisos));
    my %perfiles;
    while ($salida->fetch) {
        $perfiles{$perfil_id} = {
            'nombre' => $nombre,
            'descripcion' => $descripcion,
            'permisos' => $permisos,
        };
    }
    $salida->finish;
    return %perfiles;
}

sub get_groups {
    return @GROUP_DESCRIPTORS;
}

sub html_profiler {
    my $html = $_[0];
    my %groups = &get_profile_permissions();

    foreach my $group (keys %GROUPS) {
        if (!exists $groups{$group}) { # si el grupo no existe en los del usuario, se borra del html.
            $html =~ s/%%profile_group_$group%%.*?%%\/profile_group_$group%%//sg;
            $group = uc $group;
            $html =~ s/<!--PROFILE_GROUP_$group-->.*?<!--\/PROFILE_GROUP_$group-->//sg;
        } else {
            $html =~ s|%%/?profile_group_$group%%||sg;
            $group = uc $group;
            $html =~ s|<!--/?PROFILE_GROUP_$group-->||sg;
        }
    }

    return $html;
}


# guarda los permisos asignados a un perfil
sub save_profile_permissions {
    my ($new_profiles, $profile_id) = @_;

    my $sql = "update PROFILES set PROFILES_PERMISSIONS = ? where PROFILES_ID = ?";
    my @params = ($new_profiles, $profile_id);
    my ($bd, $msg_err_bd) = lib_prontus::conectar_user_bd();
    my $salida = glib_dbi_03::ejecutar_sql_param($bd, $sql, \@params);
    return 1;
}

sub save_profile {
    my ($profile_name, $profile_description, $permissions, $profile_id) = @_;

    my $sql = "insert into PROFILES (PROFILES_ID, PROFILES_NOM, PROFILES_DESC, PROFILES_PERMISSIONS) values (?, ?, ?, ?) on duplicate key update PROFILES_NOM = ?, PROFILES_DESC = ?, PROFILES_PERMISSIONS = ?";
    my @params = ( $profile_id, $profile_name, $profile_description, $permissions, $profile_name, $profile_description, $permissions);
    my ($bd, $msg_err_bd) = lib_prontus::conectar_user_bd();
    my $salida = glib_dbi_03::ejecutar_sql_param($bd, $sql, \@params);
    return 1;
}

# Borra un perfil de la db;
sub delete_profile {
    my $profile_id = shift;
    # no se puede borrar el perfil id 1.
    if ($profile_id < 2) {
        return 0;
    }
    my $sql = "delete from PROFILES where PROFILES_ID = ?";
    my @params = ($profile_id);
    my ($bd, $msg_err_bd) = lib_prontus::conectar_user_bd();
    my $salida = glib_dbi_03::ejecutar_sql_param($bd, $sql, \@params);
    return 1;
}

sub get_name {
    my $profile_id = $_[0];

    return 'admin' if ($profile_id eq '1' || $profile_id eq 'A');

    if (check_exists($profile_id)) {
        return $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PROFILES'}{$profile_id}{'name'};
    }

    return '';
}

sub get_profile_permissions {
    my $profile_id = $_[0];
    $profile_id = $prontus_auth::USERS_PERFIL if !$profile_id; # si no pasan un id, usamos el id del usuario logueado.

    my (%grupos, @grupos_array);
    if (!$profile_id) { # usuario no logueado
        return %grupos;
    } elsif ($profile_id == 1) { # admin
        @grupos_array = keys %GROUPS;
        %grupos = map { $_ => 1 } @grupos_array;

        return %grupos;
    } else {
        my $sql = "select PROFILES_PERMISSIONS from PROFILES where PROFILES_ID = ?";
        my $grupos;
        my @params = ($profile_id);
        my ($bd, $msg_err_bd) = lib_prontus::conectar_user_bd();
        my $salida = glib_dbi_03::ejecutar_sql_bind_param($bd, $sql, \@params, \($grupos));

        $salida->fetch;
        $salida->finish;

        @grupos_array = split /,/, $grupos;
        %grupos = map { $_ => 1 } @grupos_array;

        return %grupos;
    }
}

sub check_exists {
    my $perfil_id = $_[0];

    &load_profiles();
    if (!exists $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PROFILES'}{$perfil_id}) {
        return 0;
    }

    return 1;
}

sub check_in_use {
    my $profile_id = $_[0];

    foreach my $user_id (keys %{$prontus_varglb::USER_DATA{$prontus_varglb::PRONTUS_ID}}) {
        if ($prontus_varglb::USER_DATA{$prontus_varglb::PRONTUS_ID}{$user_id}{'USERS_PERFIL'} == $profile_id) {
            return 1;
        }
    }

    return 0;
}

sub check_has_subgroups {
    my @array = @{$_[0]};
    my @final;

    foreach my $item (@array) {
        if ($item =~ /^\.(.*?)$/) { # es otro grupo
            my $grupo = $1;
            my @listado = @{$GROUPS{$grupo}};
            @listado = &check_has_subgroups(\@listado);

            @final = (@final, @listado);
        } else {
            push @final, $item;
        }
    }

    return @final;
}


# chequea si existe acceso para el perfil dado.
# params
# grupo de permisos solicitado según el perfil
# si el profile_id es 1 (admin) retorna siempre true.
#
# retorna
# bool
sub check_profile_access {
    my @permisos_necesarios = @_;

    # bypass si es perfil admin (control total)
    return 1 if $prontus_auth::USERS_PERFIL == 1;

    my %groups = &get_profile_permissions();

    # obtenemos del sistema el nombre de la CGI actual, $0 es el nombre del archivo ejecutándose.
    $0 =~ /([a-zA-Z0-9_]+)\.\w+$/;
    my $current_cgi = $1;
    # print STDERR "current_cgi $current_cgi\n";

    foreach my $group (@permisos_necesarios) {
        if (exists $groups{$group}) {
            # print STDERR "group[$group]\n";
            my @cgilist = @{$GROUPS{$group}};

            return 1 if (!scalar @cgilist); # si no hay cgis, es solo un permiso sin restriccion x cgi. si el usuario lo tiene, pasa.
            # Si tiene subgrupos retorna el arreglo con el listado de cgi total.
            @cgilist = &check_has_subgroups(\@cgilist);

            foreach my $cgi (@cgilist) {
                # print STDERR "cgi[$cgi]\n";
                return 1 if ($current_cgi eq $cgi); # tiene acceso a la cgi.
            }
        }
    }
    # print STDERR "sin acceso\n";

    return 0; # no tiene acceso.
}

return 1;
