#!/usr/bin/perl

use strict;
use warnings;

use IO::File;
use File::Slurp;
use Getopt::Long;

our $VERSION = 0.3;

my $dont_update     = 0;
my $force_parcial   = 0;
my $record_changes  = 0;

my $record_file     = q(waste.log);

GetOptions(
        "n|dry-run"         => \$dont_update, 
        "f|force-parcial"   => \$force_parcial,
        "r|record-changes"  => \$record_changes,
) or die "bad parameters";

while (@ARGV) {
    my $model = shift @ARGV;

    my $fullpath = build_source_path( $model );
    if (not -e $fullpath and not $force_parcial) {
        warn "article ${model} in ${fullpath} don't exist";
        next;
    }
    

    # Con el modelo original y su ruta de archivo completa 
    # pasamos a crear el resto de los elementos que 
    # necesitamos    
    # 
    my $final_model = build_target_model( $model );
    my $new_path    = build_target_path( $final_model );

    # si no hemos podido ...
    if (not $new_path) {
        warn "could not build a target path";
        next;
    }

    # movemos el archivo a su nueva localización 
    rename_file($fullpath, $new_path);

    # actualizamos los catálogos 
    my @catalogs = <lang/??>;
    while (my $catpath = shift @catalogs) {
        update_catalog( $catpath, $model);
    }

    # movemos las imágenes completas, 
    move_extra_files($model, <img/$model*.jpg>);

    # las miniaturas, 
    move_extra_files($model, <th/$model*.jpg>);

    # las imágenes para impresión, 
    move_extra_files($model, <docs/print/$model*.jpg>);

    # y las páginas extras 
    move_extra_files($model, <pages/$model*>);

    if ($record_changes) {
        # registramos los cambios proporcionándole el modelo original y el
        # modelo final 
        log_activity($model,$final_model);
    }   
}

sub move_extra_files {
    my  ($model, @lista) = @_;
    my  $target_branch  = q(waste);

    # extraemos del modelo las subramas para cambiarlas a la nueva
    my ($branches) = split(m{_}, $model);

    foreach my $source_file (@lista) {
        (my $target_file = $source_file) =~ s{$branches}{$target_branch}xms;

        if (-e $source_file) {
            print "Moving ${source_file} to ${target_file} ... ";

            if (not $dont_update) {
                qx/mv $source_file $target_file/;
                print "done\n";
            }
            else {
                print "dry run\n";
            }
        }
    }
}

sub build_target_model {
    my  $model          = shift;

    my  $name = parse_model_name( $model );

    return sprintf("waste_%s", $name );
}

sub build_source_path {
    my  $model          = shift;

    return "arts/${model}";
}

sub build_target_path {
    my  $final_model    =   shift;

    # unimos el modelo final en la carpeta correspondiente 
    return sprintf("%s/%s", q(arts), $final_model);
}

sub parse_model_name {
    my  $model_name =   shift;

    # si el nombre del modelo contiene la ruta extraemos los componentes
    # (recordando que se separan con un guión bajo)
    if ($model_name =~ m{/} and $model_name =~ m{^(\w+)/([\w-]+)_([\.\w\d-]+)$}) {
        # Return folder, branches and model name or only model name 
        return wantarray ? ( $1, $2, $3 ) : $3;
    }
    elsif ($model_name =~ m{^([\w-]+)_([\.\w\d-]+)$}) {
        # return a null folder parameter
        return wantarray ? ( undef , $1, $2 ) : $2;
    }
    else {
        # return a empty list or a undef
        return wantarray ? ( ) : undef;
    }
}
    
sub rename_file {
    my  $source_file = shift;
    my  $target_file = shift;

    print "Moving ${source_file} to ${target_file} ... ";

    if ($dont_update) {
        print "dry run\n";
    }
    elsif (not -e $source_file) {
        print "not found\n";
    }
    else {
        qx/mv -f ${source_file} ${target_file}/;
        print "done\n";
    }
}

sub update_catalog {
    my  ($catalog, @models) = @_;

    # leemos el catálogo en memoria 
    my @text_catalog = read_file( $catalog );

    my $catalog_counter = 0;

    print "Updating catalog ${catalog}\n";

    # por cada uno de los modelos 
    while (@models) {
        my $active_name = shift @models;

        # obtenemos el código de modelo retirado 
        my $waste_name = build_waste_name( $active_name );
        my $search = qr{^$active_name};
        
        my $counter = 0;
        print "\tsearching ${active_name} and replace for ${waste_name} ... ";  
        foreach my $num (0 .. $#text_catalog) {
            if ($text_catalog[$num] =~ m{$search}) {
                $text_catalog[$num] =~ s!$search!$waste_name!em;
                $counter++;
            }
        }
        print "found ${counter} lines\n";

        # acumulamos en el contador por catálogo
        $catalog_counter += $counter;
    }

    if (not $dont_update) {
        print "\tWriting the updated version on disk ... ";
        if (not $catalog_counter) {
            print "zero changes done\n";
        }
        elsif (write_file( $catalog, @text_catalog ) == 1) {
            print "done\n";
        }
        else {
            print "failed ! \n";
        }
    } 
    else {
        print "\tdry run\n";
    }

    return;
}

sub build_waste_name {
    my  $current_name   =   shift;

    # le quitamos las ramas y subramas y las sustituímos por una única sección
    # ...
    $current_name =~ s{^[\w-]+_}{waste_};

    return $current_name;
}

sub log_activity {
    my  ($modelo_inicial, $modelo_final) = @_;
    
    if (my $rec = IO::File->new( $record_file, ">>" )) {
        $rec->print( 
            sprintf( "%ld:%s:%s\n", scalar time, $modelo_inicial, $modelo_final)
                );
        $rec->close();
    }

    return;
}

