#!/usr/bin/perl -w
#
# Zymonic Business Process and Information Management System
# Copyright Zednax Limited 2008 -
# For Authors and Changelog see the subversion history
use strict;

# Modules
use Zymonic::Config;
use Zymonic::DB;
use Zymonic::Table;
use Zymonic::Auth;

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

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

my $system = clean( $ARGV[0], "_" );

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

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

unless ( $db->isa('Zymonic::DB::Oracle') )
{
    print "Not an Oracle DB.\n";
    exit(1);
}

foreach my $table ( map { $config->get_def( 'Table', $_->{ZName}->{content} ) } get_array( $config->SysDef->{Table} ) )
{
    my $table_zname = $table->{ZName}->{content};
    my $table_name = ( ref( $table->{SQLName} ) eq 'HASH' ? $table->{SQLName}->{content} : $table->{ZName}->{content} );

    foreach my $key ( get_array( $table->{Key} ) )
    {
        if ( ref( $key->{Autoincrement} ) && $key->{Autoincrement}->{content} eq 'true' )
        {
            my $field = (
                grep {
                    $key->{FieldName}->{content} eq (
                        ref( $_->{SQLName} ) eq 'HASH'
                        ? $_->{SQLName}->{content}
                        : $_->{ZName}->{content}
                      )
                  } map { $config->get_def( 'Field', $_->{ZName}->{content} ) } get_array( $table->{Field} )
            )[0];
            if ($field)
            {
                my $field_zname = $field->{ZName}->{content};
                my $field_name =
                  ( ref( $field->{SQLName} ) eq 'HASH' ? $field->{SQLName}->{content} : $field->{ZName}->{content} );

                my $old_trigger_name = "${table_zname}${field_zname}t";
                my $old_seq_name     = "${table_zname}${field_zname}s";
                my $new_trigger_name = "${table_name}${field_name}t";
                my $new_seq_name     = "${table_name}${field_name}s";

                # check if trigger exists, only change if it doesn't
                # for some reason doing: SELECT * FROM user_triggers WHERE trigger_name = ?
                # does work, try to enable trigger instead and catch errors
                my $trigger_exists = 1;
                eval {
                    $trigger_exists =
                      $db->run_statement( { string => "ALTER TRIGGER  $new_trigger_name ENABLE", params => [] } );
                    1;
                  }
                  or do
                {
                    my $exception = $@;
                    if ( ref($exception) )
                    {
                        if (   $exception->isa('Zymonic::Exception::Db::Query_Run')
                            && $exception->{sql_err} =~ /trigger (.*) does not exist/i )
                        {
                            $trigger_exists = 0;
                        }
                        else
                        {
                            $exception->rethrow;
                        }
                    }
                    else
                    {
                        if ( $exception =~ /trigger (.*) does not exist/i )
                        {
                            $trigger_exists = 0;
                        }
                        else
                        {
                            die $exception;
                        }
                    }
                };

                unless ($trigger_exists)
                {
                    eval { $db->run_statement( { string => "RENAME $old_seq_name TO $new_seq_name", params => [] } ); }
                      or do
                    {
                        my $exception = $@;
                        if ( ref($exception) )
                        {
                            if (   $exception->isa('Zymonic::Exception::Db::Query_Run')
                                && $exception->{sql_err} !~ /(.*) does not exist/i )
                            {
                                $exception->rethrow;
                            }
                        }
                        else
                        {
                            if ( $exception !~ /(.*) does not exist/i )
                            {
                                die $exception;
                            }
                        }
                    };
                    eval {
                        $db->run_statement(
                            {
                                string => "DROP TRIGGER $old_trigger_name",
                                params => []
                            }
                        );
                          or do
                        {
                            my $exception = $@;
                            if ( ref($exception) )
                            {
                                if (   $exception->isa('Zymonic::Exception::Db::Query_Run')
                                    && $exception->{sql_err} !~ /(.*) does not exist/i )
                                {
                                    $exception->rethrow;
                                }
                            }
                            else
                            {
                                if ( $exception !~ /(.*) does not exist/i )
                                {
                                    die $exception;
                                }
                            }
                        };
                        eval {
                            $db->run_statement(
                                {
                                    string =>
"CREATE TRIGGER $new_trigger_name BEFORE INSERT ON $table_name FOR EACH ROW BEGIN "
                                      . "SELECT $new_seq_name.nextval INTO :new.$field_name FROM DUAL; END;",
                                    params => []
                                }
                            );
                              or do
                            {
                                my $exception = $@;
                                if ( ref($exception) )
                                {
                                    if (   $exception->isa('Zymonic::Exception::Db::Query_Run')
                                        && $exception->{sql_err} !~ /(.*) does not exist/i )
                                    {
                                        $exception->rethrow;
                                    }
                                }
                                else
                                {
                                    if ( $exception !~ /(.*) does not exist/i )
                                    {
                                        die $exception;
                                    }
                                }
                            };
                        };
                    };
                }
            }

        }
