#!/usr/bin/perl -w -T

# TODO rewrite/replace with new dynamic fields if needed.

# Library path
BEGIN
{
    use vars qw($location $script_name $script_location $utils $debugfile);
    use Zymonic::Utils qw(clean debug death_handler);
    $main::SIG{__DIE__} = \&death_handler;

}

use Zymonic::Config;
use Zymonic::Session;
use Zymonic::DB;
use Zymonic::Auth;

$debugfile = STDERR;

my $action = clean( $ARGV[0] ) or die "Need to specifiy 'create' or 'delete' as argument\n";
die "Need to specifiy 'create' or 'delete' as argument\n" if $action ne 'create' && $action ne 'delete';
my $user = clean( $ARGV[1] ) || '';
my $ip_address = clean( $ARGV[2] ) || clean( $ENV{REMOTE_ADDR} ) || '127.0.0.1';

my $protocol = ( ( defined( $ENV{HTTPS} ) and $ENV{HTTPS} eq 'on' ) ? 'https' : 'http' );

# Clean path
$ENV{PATH} = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/sbin:/usr/sbin";

# Create a session (CGI only)
$ENV{SERVER_NAME} = clean( $ENV{SERVER_NAME}, "-_" );
my $session = Zymonic::Session->new(
    ip_address => $ip_address,
    protocol   => $protocol
);

my $system = $session->system_name( $ENV{SERVER_NAME}, "/etc/zymonic" );

my $config = Zymonic::Config->new(
    system_name => $system,
    config_dir  => "/etc/zymonic",
    ip_address  => $ip_address,
    protocol    => 'https'
);

$session->{config} = $config;

my $db = Zymonic::DB->new( config => $config );

$session->{DB} = $db;

my $auth = Zymonic::Auth->new(
    config      => $config,
    session     => $session,
    DB          => $db,
    credentials => '',
    ip_address  => $session->ip_address
);
$auth->user($user);
$auth->logged_in( $user ? 'Y' : '' );
$auth->initialise();

$session->{auth} = $auth;
$session->{user} = $user || '';

$session->cgi->param( 'ZZpagename', 't_006_countries_page' );
my $actual_result = $session->view_control;
my $process_id = $actual_result->{currentpage}->{location}->[0]->{block}->[0]->{t_006_countries_process}->{process_id};

my @test_data_order = qw(t_006_countries t_006_cities t_006_people);

my $test_data = {
    t_006_countries => {
        England => { id => '', set_values => { t_006_country_name => '\'England\'' }, },
        France  => { id => '', set_values => { t_006_country_name => '\'France\'' }, },
        Spain   => { id => '', set_values => { t_006_country_name => '\'Spain\'' }, }
    },
    t_006_cities => {
        London => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'London\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{England}->{id}',
                t_006_suburbs         => 197,
                t_006_population      => 7421000,
            },

        },
        Liverpool => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Liverpool\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{England}->{id}',
                t_006_suburbs         => 40,
                t_006_population      => 434900,
            },

        },
        Manchester => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Manchester\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{England}->{id}',
                t_006_suburbs         => 53,
                t_006_population      => 464200,
            },

        },
        Birmingham => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Birmingham\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{England}->{id}',
                t_006_suburbs         => 11,
                t_006_population      => 1016800,
            },

        },
        Newcastle => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Newcastle\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{England}->{id}',
                t_006_suburbs         => 40,
                t_006_population      => 273600,
            },

        },
        Paris => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Paris\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{France}->{id}',
                t_006_suburbs         => 20,
                t_006_population      => 10142983,
            },

        },
        Nice => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Nice\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{France}->{id}',
                t_006_suburbs         => 14,
                t_006_population      => 347060,
            },

        },
        Bordeaux => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Bordeaux\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{France}->{id}',
                t_006_suburbs         => 8,
                t_006_population      => 250082,
            },

        },
        Madrid => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Madrid\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{Spain}->{id}',
                t_006_suburbs         => 21,
                t_006_population      => 3213271,
            },

        },
        Barcelona => {
            id         => '',
            set_values => {
                t_006_city_name       => '\'Barcelona\'',
                t_006_city_country_id => '$test_data->{t_006_countries}->{Spain}->{id}',
                t_006_suburbs         => 3210,
                t_006_population      => 1673075,
            },
        },
    },
    t_006_people => {
        Derek => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Derek\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{London}->{id}'
            },

        },
        Rodney => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Rodney\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{London}->{id}'
            },

        },
        Anton2 => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Anton\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{London}->{id}'
            },

        },
        John => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'John\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Liverpool}->{id}'
            },

        },
        Paul => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Paul\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Liverpool}->{id}'
            },

        },
        George => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'George\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Liverpool}->{id}'
            },

        },
        Ringo => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Ringo\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Liverpool}->{id}'
            },

        },
        Liam => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Liam\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Manchester}->{id}'
            },

        },
        Noel => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Noel\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Manchester}->{id}'
            },

        },
        Lenny => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Lenny\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Birmingham}->{id}'
            },

        },
        Anthony => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Anthony\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Newcastle}->{id}'
            },

        },
        Declan => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Declan\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Newcastle}->{id}'
            },

        },
        Alan => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Alan\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Newcastle}->{id}'
            },

        },
        Pierre => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Pierre\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Paris}->{id}'
            },

        },
        Jean => {
            id => '',
            set_values =>
              { t_006_person_name => '\'Jean\'', t_006_person_city_id => '$test_data->{t_006_cities}->{Paris}->{id}' },

        },
        Anton => {
            id => '',
            set_values =>
              { t_006_person_name => '\'Anton\'', t_006_person_city_id => '$test_data->{t_006_cities}->{Nice}->{id}' },

        },
        Raul => {
            id => '',
            set_values =>
              { t_006_person_name => '\'Raul\'', t_006_person_city_id => '$test_data->{t_006_cities}->{Madrid}->{id}' },

        },
        Xabi => {
            id => '',
            set_values =>
              { t_006_person_name => '\'Xabi\'', t_006_person_city_id => '$test_data->{t_006_cities}->{Madrid}->{id}' },

        },
        Kaka => {
            id => '',
            set_values =>
              { t_006_person_name => '\'Kaka\'', t_006_person_city_id => '$test_data->{t_006_cities}->{Madrid}->{id}' },

        },
        Ronaldo => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Ronaldo\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Madrid}->{id}'
            },

        },
        Lionel => {
            id         => '',
            set_values => {
                t_006_person_name    => '\'Lionel\'',
                t_006_person_city_id => '$test_data->{t_006_cities}->{Barcelona}->{id}'
            },
        },
    },
};

if ( $action eq 'create' )
{

    foreach my $key (@test_data_order)
    {
        my $data  = $test_data->{$key};
        my $table = Zymonic::Table->new(
            table  => $key,
            config => $config,
            auth   => $auth,
            db     => $db,
        );

        foreach my $name ( keys %$data )
        {

            # Get the new record placeholder and set their fields
            eval { $table->get_records( { records_per_page => 999 } ); }
              or do
            {
                my $exception = $@;
                if ( $exception
                    and !$exception->isa('Zymonic::Exception::Table::Get_Record') )
                {
                    ref $exception ? $exception->rethrow : die $exception;
                }
            };
            $table->setup_placeholder;
            my $new_rec = ( grep { $_->{id} eq $table->{placeholder_id} } @{ $table->{records} } )[0];

            # set any fields on it
            foreach my $set_key ( keys %{ $data->{$name}->{set_values} } )
            {
                ( grep { $_->field eq $set_key } @{ $new_rec->{fields} } )[0]
                  ->value( eval "$data->{$name}->{set_values}->{$set_key}" );
            }

            # set process id
            ( grep { $_->field eq 'parent_process_id' } @{ $new_rec->{fields} } )[0]->value($process_id);

            $table->before_add;
            $data->{$name}->{id} = $table->add_record;

            # set id on fields
            $new_rec->{id} = $data->{$name}->{id};
            $new_rec->{ $table->keyfield } = $data->{$name}->{id};
            ( grep { $_->field eq $table->keyfield } @{ $new_rec->{fields} } )[0]->value( $data->{$name}->{id} );

            $table->after_add( $data->{$name}->{id}, $process_id );
        }
    }
}

if ( $action eq 'delete' )
{
    foreach my $key (@test_data_order)
    {
        my $data  = $test_data->{$key};
        my $table = Zymonic::Table->new(
            table  => $key,
            config => $config,
            auth   => $auth,
            db     => $db,
        );

        foreach my $name ( keys %$data )
        {

            # lookup record id
            eval { $table->get_records( { records_per_page => 999 } ); }
              or do
            {
                my $exception = $@;
                if ( $exception
                    and !$exception->isa('Zymonic::Exception::Table::Get_Record') )
                {
                    ref $exception ? $exception->rethrow : die $exception;
                }
            };
            my $rec;
            my $search = $name;
            $search =~ s/(.*)\d/$1/;
            foreach my $record (
                grep {
                    grep { $_ && $_->{value} eq $search }
                      @{ $_->{fields} || [] }
                } @{ $table->{records} || [] }
              )
            {
                my $parent_process_field =
                  ( grep { $_ && $_->field && $_->field eq 'parent_process_id' } @{ $record->{fields} } )[0];
                my $deleted_field = ( grep { $_ && $_->field && $_->field eq 'deleted' } @{ $record->{fields} } )[0];

                if (   $parent_process_field
                    && $parent_process_field->{value}
                    && $parent_process_field->{value} eq $process_id
                    && $deleted_field
                    && ( !$deleted_field->{value} || $deleted_field->{value} ne 'Y' ) )
                {
                    $rec = $record;
                    last;
                }
            }
            if ($rec)
            {
                $table->before_delete;
                $table->delete_record( $rec->{id} );

                # check that record was deleted
                eval { $table->get_records( { records_per_page => 999 } ); }
                  or do
                {
                    my $exception = $@;
                    if ( $exception
                        and !$exception->isa('Zymonic::Exception::Table::Get_Record') )
                    {
                        ref $exception ? $exception->rethrow : die $exception;
                    }
                };
            }
        }
    }
}
