<%INIT>
# XXX: This is almost complete copy&paste of the /Search/Build.html INIT section


use RT::Interface::Web::QueryBuilder;
use RT::Interface::Web::QueryBuilder::Tree;
use RT::SQL;

my @actions;

my %query;
for( qw(Query Format OrderBy Order RowsPerPage) ) {
    $query{$_} = $ARGS{$_};
}

my %saved_search;
push @actions, $m->comp( '/Search/Elements/EditSearches:Init', %ARGS, Query => \%query, SavedSearch => \%saved_search );

if ( $NewQuery ) {
    %query = (); %saved_search = ( Id => 'new' );
    delete $session{'CurrentSearchHash'};
    $session{'tickets'}->CleanSlate if defined $session{'tickets'};
}

{ # Attempt to load what we can from the session and preferences, set defaults

    my $current = $session{'CurrentSearchHash'};
    my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {};
    my $default = { Query => '', Format => '', OrderBy => 'id', Order => 'ASC', RowsPerPage => 50 };

    for( qw(Query Format OrderBy Order RowsPerPage) ) {
        $query{$_} = $current->{$_} unless defined $query{$_};
        $query{$_} = $prefs->{$_} unless defined $query{$_};
        $query{$_} = $default->{$_} unless defined $query{$_};
    }

    for( qw(Order OrderBy) ) {
        if (ref $query{$_} eq "ARRAY") {
            $query{$_} = join( '|', @{ $query{$_} } );
        }
    }
    if ( $query{'Format'} ) {
        # Clean unwanted junk from the format
        $query{'Format'} = $m->comp( '/Elements/ScrubHTML', Content => $query{'Format'} );
    }
}

# {{{ Parse the query
my $ParseQuery = sub {
    my $string = shift;

    use RT::Interface::Web::QueryBuilder::Tree;
    my $tree = RT::Interface::Web::QueryBuilder::Tree->new('AND');
    my @errors = $tree->ParseSQL( Query => $string, CurrentUser => $session{'CurrentUser'} );

    return ($tree, @errors);
};

my ($tree, @parsing_errors) = $ParseQuery->( $query{'Query'} );

# if parsing went poorly, send them to the edit page to fix it
if ( @parsing_errors ) {
    # XXX: we have no Advanced Query Builder in RTIR, so just push errors into results
    # return $m->comp( "Edit.html", Query => $query{'Query'}, actions => \@actions );
    push @actions, @parsing_errors;
}

my @options = $tree->GetDisplayedNodes;
my @current_values = grep defined, @options[@clauses];
my @new_values = ();

# {{{ Try to find if we're adding a clause
foreach my $arg ( keys %ARGS ) {
    next unless $arg =~ m/^ValueOf(\w+|'CF.{.*?}')$/
                && ( ref $ARGS{$arg} eq "ARRAY"
                     ? grep $_ ne '', @{ $ARGS{$arg} }
                     : $ARGS{$arg} ne '' );

    # We're adding a $1 clause
    my $field = $1;

    my ($op, $value);

    #figure out if it's a grouping
    my $keyword = $ARGS{ $field . "Field" } || $field;

    my ( @ops, @values );
    if ( ref $ARGS{ 'ValueOf' . $field } eq "ARRAY" ) {
        # we have many keys/values to iterate over, because there is
        # more than one CF with the same name.
        @ops    = @{ $ARGS{ $field . 'Op' } };
        @values = @{ $ARGS{ 'ValueOf' . $field } };
    }
    else {
        @ops    = ( $ARGS{ $field . 'Op' } );
        @values = ( $ARGS{ 'ValueOf' . $field } );
    }
    RT->Logger->error("Bad Parameters passed into Query Builder")
        unless @ops == @values;

    for ( my $i = 0; $i < @ops; $i++ ) {
        my ( $op, $value ) = ( $ops[$i], $values[$i] );
        next if !defined $value || $value eq '';

        if ( $value eq 'NULL' && $op =~ /=/ ) {
            if ( $op eq '=' ) {
                $op = "IS";
            }
            elsif ( $op eq '!=' ) {
                $op = "IS NOT";
            }

            # This isn't "right", but...
            # It has to be this way until #5182 is fixed
            $value = "'NULL'";
        }
        else {
            $value = "'$value'";
        }

        my $clause = {
            Key   => $keyword,
            Op    => $op,
            Value => $value
        };

        push @new_values, RT::Interface::Web::QueryBuilder::Tree->new($clause);
    }
}

# }}}

push @actions, $m->comp('/Search/Elements/EditQuery:Process',
    %ARGS,
    Tree => $tree,
    Selected => \@current_values,
    New => \@new_values,
);

# {{{ Rebuild $Query based on the additions / movements

my $optionlist_arrayref;
($query{'Query'}, $optionlist_arrayref) = $tree->GetQueryAndOptionList(\@current_values);

my $optionlist = join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>) 
                                  . ("&nbsp;" x (5 * $_->{DEPTH}))
                                  . $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @$optionlist_arrayref;

# }}}

my $queues = $tree->GetReferencedQueues;

# Parse queues from BaseQuery
if ( $BaseQuery ) {
    my ($tree) = $ParseQuery->( $BaseQuery );
    $queues = { %$queues, %{ $tree->GetReferencedQueues } };
}

# XXX: dequote queues hash
# why we should do this? may be it's bug.
foreach my $q ( keys %$queues ) {
    next unless $q =~ /^['"](.*)['"]$/;
    $queues->{ $1 } = delete $queues->{ $q };
}

# {{{ Deal with format changes
my ( $AvailableColumns, $CurrentFormat );
( $query{'Format'}, $AvailableColumns, $CurrentFormat ) = $m->comp(
    '/Search/Elements/BuildFormatString',
    %ARGS,
    cfqueues => $queues,
    Format => $query{'Format'},
);

# }}}

# if we're asked to save the current search, save it
push @actions, $m->comp( '/Search/Elements/EditSearches:Save', %ARGS, Query => \%query, SavedSearch => \%saved_search );

# {{{ Push the updates into the session so we don't loose 'em

$session{'CurrentSearchHash'} = {
    %query,
    SearchId    => $saved_search{'Id'},
    Object      => $saved_search{'Object'},
    Description => $saved_search{'Description'},
};

# }}}

# {{{ Show the results, if we were asked.
if ( $ARGS{"DoSearch"} ) {
    $ResultPage .= $ResultPage =~ /\?/? '&': '?';
    $ResultPage .= $m->comp('/Elements/QueryString', %query );
    $m->redirect( RT->Config->Get('WebURL') . $ResultPage );
    $m->abort();
}
# }}}

return (
    query            => \%query,
    saved_search     => \%saved_search,
    results          => \@actions,
    optionlist       => $optionlist,
    queues           => $queues,
    AvailableColumns => $AvailableColumns,
    CurrentFormat    => $CurrentFormat,
);

</%INIT>

<%ARGS>
$NewQuery  => 0
@clauses   => ()

$BaseQuery => ''
$ResultPage => "RTIR/Search/Results.html"
</%ARGS>
