package DBIx::dbMan::Extension::Transaction;

use strict;
use base 'DBIx::dbMan::Extension';

our $VERSION = '0.10';

1;

sub IDENTIFICATION { return "000001-000022-000010"; }

sub preference { return 0; }

sub known_actions { return [ qw/TRANSACTION NOTIFY/ ]; }

sub init {
	my $obj = shift;

	$obj->{prompt_num} = $obj->{-interface}->register_prompt(1000);
	$obj->{prompt_title} = $obj->{-config}->prompt_transaction || 'TRANSACTION';
}

sub menu {
	my $obj = shift;

	if ($obj->{-dbi}->current and $obj->{-dbi}->in_transaction) {
		return ( { label => 'Transaction', submenu => [
				{ label => 'Commit transaction',
					action => { action => 'TRANSACTION',
						operation => 'commit' } },
				{ label => 'Rollback transaction',
					action => { action => 'TRANSACTION',
						operation => 'rollback' } },
				{ label => 'Auto commit transaction', preference => -20,
					action => { action => 'TRANSACTION',
						operation => 'end' } },
				{ separator => 1, preference => -10 }
			] } );
	} else {
		return ( { label => 'Transaction', submenu => [
				{ label => 'Begin transaction',
					action => { action => 'TRANSACTION',
						operation => 'begin' } }
			] } );
	}
}

sub handle_action {
	my ($obj,%action) = @_;

	if ($action{action} eq 'TRANSACTION') {
		if ($action{operation} =~ /^(begin|end|commit|rollback)$/) {
			$action{action} = 'NONE';
			unless ($obj->{-dbi}->current) {
				$obj->{-interface}->error("No current connection selected.");
				return %action;
			}
			if ($obj->{-dbi}->in_transaction and $action{operation} eq 'begin') {
				$obj->{-interface}->error('Transaction already started.');
				return %action;
			} elsif (not $obj->{-dbi}->in_transaction and $action{operation} =~ /^(end|commit|rollback)$/) {
				$obj->{-interface}->error('No transaction started.');
				return %action;
			}

			if ($action{operation} eq 'begin') {
				$obj->{-dbi}->trans_begin;
				$action{output} = "Transaction started.\n";
			} elsif ($action{operation} eq 'end') {
				$obj->{-dbi}->rollback;
				$obj->{-dbi}->trans_end;
				$action{output} = "Auto commit transaction mode started with implicit rollback.\n";
			} elsif ($action{operation} eq 'commit') {
				$obj->{-dbi}->commit;
				$action{output} = "Transaction commited.\n";
			} elsif ($action{operation} eq 'rollback') {
				$obj->{-dbi}->rollback;
				$action{output} = "Transaction rolled back.\n";
			}
			$action{action} = 'OUTPUT';
			$obj->{-interface}->rebuild_menu();
	    } elsif ( $action{action} eq 'NOTIFY' and $action{notify} eq 'connection_change' ) {
            # prompt will be applied later in this handler
		} elsif ($action{operation} eq 'change') {
			$action{action} = 'NONE';
			$obj->{-interface}->rebuild_menu();
		}
	}

	if ($obj->{-dbi}->in_transaction) {
		$obj->{-interface}->prompt($obj->{prompt_num},$obj->{prompt_title});
	} else {
		$obj->{-interface}->prompt($obj->{prompt_num},'');
	}

	$action{processed} = 1;
	return %action;
}

sub done {
	my $obj = shift;
	
	$obj->{-interface}->deregister_prompt($obj->{prompt_num});

	for (@{$obj->{-dbi}->list('active')}) {
		my $name = $_->{name};
		$obj->{-dbi}->set_current($name);		# nic nevypisovat
		if ($obj->{-dbi}->in_transaction()) {
			$obj->{-dbi}->rollback;
			$obj->{-dbi}->trans_end;
			$obj->{-interface}->print("Transaction end with implicit rollback in connection $name.\n");
		}
	}
}