package Opals::Eq_SolrSearch;

#require Exporter;
#@ISA       = qw(Exporter);

# Version number
$VERSION   = 0.01;      

#use utf8;
use strict;
use Encode;
use LWP::UserAgent;
use HTTP::Request::Common;
use Time::localtime;
use JSON;

my $tm = localtime;

my $sortFieldMap={
    eq_name =>'eq_name_sort+<sortDir>,1_sort+<sortDir>,3_sort+<sortDir>,rid_sort+<sortDir>',
    1 => '1_sort+<sortDir>,eq_name_sort+<sortDir>,3_sort+<sortDir>,rid_sort+<sortDir>',
    3 => '3_sort+<sortDir>,eq_name_sort+<sortDir>,1_sort+<sortDir>,rid_sort+<sortDir>',
    eq_barcode => 'eq_barcode+<sortDir>'
};

my $facetFieldMap = {
    category=>"category_facet",
    building=>"building_facet"
};

my $eq_sortFieldMap={
    eq_name =>'eq_name_sort+<sortDir>',
    eq_manufacturer => 'eq_manufacturer_sort+<sortDir>',
    eq_model => 'eq_model_sort+<sortDir>',
    eq_name1 =>'eq_name_sort+<sortDir>,eq_manufacturer_sort+<sortDir>,eq_model_sort+<sortDir>,eq_rid_sort+<sortDir>',
    eq_manufacturer1 => 'eq_manufacturer_sort+<sortDir>,eq_name_sort+<sortDir>,eq_model_sort+<sortDir>,eq_rid_sort+<sortDir>',
    eq_model1 => 'eq_model_sort+<sortDir>,eq_name_sort+<sortDir>,eq_manufacturer_sort+<sortDir>,eq_rid_sort+<sortDir>',
    eq_barcode => 'eq_barcode+<sortDir>'
};

my $eq_facetFieldMap = {
    category=>"category_facet",
    building=>"building_facet"
};
=item
my $eq_facetFieldMap = {
    category=>"eq_category_facet",
    building=>"eq_building_facet"
};
=cut

sub new {
    my $class = shift;
    my (%param) = (@_);
    my $dbh = $param{'dbh'};
    return unless $dbh;
    my $this = {
        dbh => $dbh,
    };
    bless $this, $class;
    return $this;
}
################################################################################
# Search Solr
# 
################################################################################
# build Querry
sub eq_slr_srchQuery {
    my $this = shift;
    my ($input) = @_;
    my $luceneQuery ="fq=db:equipment&facet=true&facet.limit=-1";
    if ($input->{'groupBy'} eq "barcode" || $input->{'displayStyle'} eq 'linear'){
      $luceneQuery .= "&group.ngroups=true&group=true&group.field=eq_barcode";
    }
    else{
      $luceneQuery .= "&facet=true&group.ngroups=true&group=true&group.field=rid";
    }
    while (my ($k,$v) = each %{$eq_facetFieldMap}){
      $luceneQuery .= "&facet.field=" . $v;
    }
    my $sTerm       = $input->{'kw'};
    my $sField      = $input->{'srchField'}||$input->{'sField'}||$input->{'field'}||$input->{'sfield'}||"0";
    my $sExctMatch  = $input->{'exactmatch'}||$input->{'exactMatch'};
    my $sortAttr    = $input->{'sortAttr'};
    my $sortDir     = $input->{'sortOrder'};
    my $offset      = $input->{'offset'};
    my $pSize       = $input->{'pSize'};
    my $searchByCat = $input->{'searchByCat'};
    my $catCode     = $input->{'cat'};
    my $building    = $input->{'bldList'} || $input->{'bldId'};
    my $notContain  = $input->{'notContain'};
    my $pSize       = $input->{'pSize'}|| 10;
    my $pNum        = $input->{'pNum'} || $input->{'pNo'};
    my $rid         = $input->{'rid'};
    my $ridSel      = $input->{'ridSel'};
    if (!defined $offset || $offset <=0){
      $offset = ($pNum - 1) * $pSize;
    }
    my ($catSearch,$simpleSearch,$advancedSearch) = (0,0,0);
    $catSearch = ($searchByCat  && $searchByCat > 0)? 1: 0;
    $simpleSearch = ($input->{'kw'} && $input->{'kw'} ne "") ? 1:0;
    $advancedSearch = ($input->{'kw1'} ne "" || $input->{'kw2'} ne "" || $input->{'kw3'} ne "")?1:0;
    if ($catSearch == 1) {
        if ($catCode && $catCode ne ""){
            $luceneQuery .= "&q=category:($catCode)";
        }
        else{
            $luceneQuery .= "&q=category:\*";
        }
    }
    elsif ($advancedSearch == 1){
        my ($sField1,$sField2,$sField3)= ("","","");
        my ($q,$q1,$q2,$q3)=("","","","");
        if ($input->{'kw1'} ne "" ){
            $q1=$input->{'sfield1'} . ":(" . $input->{'kw1'} . ") ";
        }
        if ($input->{'kw2'} ne "" ){
            $q2 .=$input->{'sfield2'} . ":(" . $input->{'kw2'} . ") ";
        }
        if ($input->{'kw3'} ne "" ){
            $q3 .=$input->{'sfield3'} . ":(" . $input->{'kw3'} . ")";
        }
        $q = $q1;
        if ($q2 ne "" && $q3 ne ""){
            $q .= uc($input->{'cfield1'}) . " (" . $q2 .  uc($input->{'cfield2'}) ." ". $q3 . ")";
        }
        elsif ($q2 ne "" ){
            $q .= uc($input->{'cfield1'}) . " ". $q2;
        }
        $luceneQuery .= "&q=$q";
    }
    else { #simple search
        if ($sField eq "0" || !$sField){
            if ($sExctMatch && $sExctMatch eq "1"){
                $luceneQuery .= "&q=eq_anywhere_exct:(\"$sTerm\")";
            }else{
                $luceneQuery .= "&q=eq_anywhere:($sTerm)";
            }
        }
        else{
            if ($sExctMatch && $sExctMatch eq "1"){
                $luceneQuery .= "&q=". $sField ."_exct:(\"" . $sTerm ."\")";
            }else{
                if ($notContain && $notContain eq '1') {
                    $luceneQuery .= "&q=!$sField:($sTerm)";
                }
                elsif (defined $sField && $sField ne ""){
                    $luceneQuery .= "&q=$sField:($sTerm)";
                }
                else{
                    $luceneQuery .= "&q=eq_anywhere:($sTerm)";
                }
            }
        }
    }

    open debug ,">/tmp/debugKK";
    print debug "input: ", to_json($input), "\n";
      print debug "building 1 :$building \n";
    if (defined $building && $building ne "" && $building ne '0'){
      print debug "building 2 :$building \n";
        $luceneQuery .= " AND 18:($building)";
    }
    $luceneQuery .= "&start=" . $offset . "&rows=" . $pSize;
    #my $sortCond = $eq_sortFieldMap->{$sortAttr};
    my $sortCond = $sortFieldMap->{$sortAttr};
    if ($sortDir eq "1"){
        $sortDir = "asc";
    }
    else{
        $sortDir = "desc";
    }
    $sortCond =~ s/<sortDir>/$sortDir/g;
    $luceneQuery .= "&sort=$sortCond";
    #$luceneQuery .= "&fl=*";
    if ($input->{'wt'} eq "json" || !$input->{'wt'}){
      $luceneQuery .= "&wt=json";
    }
    print debug "luceneQuery: $luceneQuery \n";
    close debug;
    return "$luceneQuery";
}

# Solr Search
sub eq_slr_search {
    my $this = shift;
    my $dbh     = $this->{'dbh'};
    my ($params)= @_;
    my ($hits,@result) = (0,());
    open debug ,">/tmp/ES";
    print debug "params from eq_slr_search>>",to_json($params,{pretty=>1}),"\n";
    if (!defined $params->{'lQuery'} || $params->{'lQuery'} eq ''){
        return {hits=>0,recordList=>undef};
    }
    print debug "dipslayStyle", $params->{'displayStyle'}, "\n";
    my($sHost,$sPort,$sDatabase,$db_name) = $this->eq_getSolrSrvInfo();
    my $url="http://$sHost:$sPort/solr/$db_name/select?" . $params->{'lQuery'} ;
    print debug "url:$url \n";
    my $data = _querySolr($url);
    #print debug "data", $data , "\n";
    my $result = $data?decode_json($data):{};
    if ($params->{'displayStyle'} eq "linear" ||$params->{'displayStyle'} eq "barcode"|| $params->{'groupBy'} eq "barcode" || $params->{'groupBy'} eq "eq_barcode"){
        $hits = $result->{'grouped'}->{'eq_barcode'}->{'matches'} ;
        print debug "hits:$hits";
    }
    else{
        $hits = $result->{'grouped'}->{'rid'}->{'ngroups'} ;
    }
    print debug "HITS:$hits \n";
    my $facetList = getFacetListJson($result);
    my $fieldMap = {};
    my $recList = getRecordFieldsJson($dbh,$result,$fieldMap,$params->{'displayStyle'});
    print debug "recList" , to_json($recList,{pretty=>1}),"\n";
    close debug;
    return {hits=>$hits,recordList=>$recList,facetList=>$facetList};
}

sub eq_slr_buildSearchQuery {
    my $this = shift;
    my ($input) = @_;
    #my $luceneQuery ="fq=db:equipment&group.ngroups=true&group=true&group.field=rid&facet=true";
    my $luceneQuery ="fq=db:equipment&facet=true&facet.limit=-1";
    if ($input->{'groupBy'} eq "barcode" || $input->{'displayStyle'} eq "linear"){
        $luceneQuery .= "&group.ngroups=true&group=true&group.field=eq_barcode";
    }
    else{
        $luceneQuery .= "&facet=true&group.ngroups=true&group=true&group.field=rid";
    }
    while (my ($k,$v) = each %{$facetFieldMap}){
        $luceneQuery .= "&facet.field=" . $v;
    }
    my $sTerm       = $input->{'kw'};
    my $sField      = $input->{'sfield'} || $input->{'sf0'} || "0"; 
    my $sExctMatch  = $input->{'exactmatch'}||$input->{'exactMatch'};
    my $sortAttr    = $input->{'sortAttr'};
    my $sortDir     = $input->{'sortOrder'};
    my $offset      = $input->{'offset'};
    my $pSize       = $input->{'pSize'};
    my $searchByCat = $input->{'searchByCat'};
    my $catCode     = $input->{'cat'};
    my $building    = $input->{'bldList'};
    my $notContain  = $input->{'notContain'};
    my $pSize       = $input->{'pSize'}|| 10;
    my $pNum        = $input->{'pNum'} || $input->{'pNo'};
    my $rid         = $input->{'rid'};
    if (!defined $offset || $offset <=0){
      $offset = ($pNum - 1) * $pSize;
    }

    my ($catSearch,$simpleSearch,$advancedSearch) = (0,0,0);
    $catSearch = ($searchByCat  && $searchByCat > 0)? 1: 0;
    $simpleSearch = ($input->{'kw'} && $input->{'kw'} ne "") ? 1:0;
    $advancedSearch = ($input->{'kw1'} ne "" || $input->{'kw2'} ne "" || $input->{'kw3'} ne "")?1:0;
    $luceneQuery .= "&rid:$rid";

    if ($catSearch == 1) {
        if ($catCode && $catCode ne ""){
            #$luceneQuery .= "&q=category:($catCode)";
            $luceneQuery .= "&q=eq_category:($catCode)";
        }
        else{
            #$luceneQuery .= "&q=category:\*";
            $luceneQuery .= "&q=eq_category:\*";
        }
    }
    elsif ($advancedSearch == 1){
        my ($sField1,$sField2,$sField3)= ("","","");
        my ($q,$q1,$q2,$q3)=("","","","");
        if ($input->{'kw1'} ne "" ){
            $q1=$input->{'sfield1'} . ":(" . $input->{'kw1'} . ") ";
        }
        if ($input->{'kw2'} ne "" ){
            $q2 .=$input->{'sfield2'} . ":(" . $input->{'kw2'} . ") ";
        }
        if ($input->{'kw3'} ne "" ){
            $q3 .=$input->{'sfield3'} . ":(" . $input->{'kw3'} . ")";
        }
        $q = $q1;
        if ($q2 ne "" && $q3 ne ""){
            $q .= uc($input->{'cfield1'}) . " (" . $q2 .  uc($input->{'cfield2'}) ." ". $q3 . ")";
        }
        elsif ($q2 ne "" ){
            $q .= uc($input->{'cfield1'}) . " ". $q2;
        }
        $luceneQuery .= "&q=$q";
    }
    else { #simple search
        if ($sField eq "0"){
            if ($sExctMatch && $sExctMatch eq "1"){
              if ($notContain && $notContain eq '1') {
                $luceneQuery .= "&q=!eq_anywhere_exct:(\"$sTerm\")";
              }
              else{
                $luceneQuery .= "&q=eq_anywhere_exct:(\"$sTerm\")";
              }
            }else{
              if ($notContain && $notContain eq '1') {
                $luceneQuery .= "&q=!eq_anywhere:($sTerm)";
              }
              else{
                $luceneQuery .= "&q=eq_anywhere:($sTerm)";
              }
            }
        }
        else{
            if ($sExctMatch && $sExctMatch eq "1"){
              if ($notContain && $notContain eq '1') {
                $luceneQuery .= "&q=!". $sField ."_exct:(\"" . $sTerm ."\")";
              }
              else{
                $luceneQuery .= "&q=". $sField ."_exct:(\"" . $sTerm ."\")";
              }
            }else{
                if ($notContain && $notContain eq '1') {
                    $luceneQuery .= "&q=!$sField:($sTerm)";
                }
                else{
                    $luceneQuery .= "&q=$sField:($sTerm)";
                }
            }
        }
    }
    if (defined $building && ($building ne "" || $building ne '0' || $building!=0)){
        $luceneQuery .= " AND 18:($building)";
    }
    $luceneQuery .= "&start=" . $offset . "&rows=" . $pSize;
    my $sortCond = $sortFieldMap->{$sortAttr};
    if ($sortDir eq "1"){
        $sortDir = "asc";
    }
    else{
        $sortDir = "desc";
    }
    $sortCond =~ s/<sortDir>/$sortDir/g;
    $luceneQuery .= "&sort=$sortCond";
    $luceneQuery .= "&wt=json";
    return "$luceneQuery";
}

sub eq_slr_buildSrchQueryJson {
    my $this = shift;
    my ($input) = @_;
    my $luceneQuery ="fq=db:equipment&facet=true&facet.limit=-1";
    if ($input->{'groupBy'} eq "barcode" || $input->{'displayStyle'} eq 'linear'){
        $luceneQuery .= "&group.ngroups=true&group=true&group.field=eq_barcode";
    }
    else{
        $luceneQuery .= "&facet=true&group.ngroups=true&group=true&group.field=rid";
    }
    while (my ($k,$v) = each %{$facetFieldMap}){
        $luceneQuery .= "&facet.field=" . $v;
    }
    my $sTerm       = $input->{'kw'};
    my $sField      = $input->{'sfield'}; 
    my $sExctMatch  = $input->{'exactmatch'}||0;
    my $sortAttr    = $input->{'sortAttr'} || "eq_name";
    my $sortDir     = $input->{'sortOrder'};
    my $offset      = $input->{'offset'};
    my $pSize       = $input->{'pSize'};
    my $searchByCat = $input->{'searchByCat'};
    my $catCode     = $input->{'cat'};
    my $building    = $input->{'bldList'};
    my $notContain  = $input->{'notContain'};
    my $pSize       = $input->{'pSize'}|| 10;
    my $pNum        = $input->{'pNum'} || $input->{'pNo'};
    my $rid         = $input->{'rid'};
    my $ridSel      = $input->{'ridSel'};
    if (!defined $offset || $offset <=0){
      $offset = ($pNum - 1) * $pSize;
    }
    my ($catSearch,$simpleSearch,$advancedSearch) = (0,0,0);
    $catSearch = ($searchByCat  && $searchByCat > 0)? 1: 0;
    $simpleSearch = ($input->{'kw'} && $input->{'kw'} ne "") ? 1:0;
    $advancedSearch = ($input->{'kw1'} ne "" || $input->{'kw2'} ne "" || $input->{'kw3'} ne "")?1:0;
    if ($catSearch == 1) {
        if ($catCode && $catCode ne ""){
            $luceneQuery .= "&q=category:($catCode)";
            #$luceneQuery .= "&q=eq_category:($catCode)";
        }
        else{
            $luceneQuery .= "&q=category:\*";
            #$luceneQuery .= "&q=eq_category:\*";
        }
    }
    elsif ($advancedSearch == 1){
        my ($sField1,$sField2,$sField3)= ("","","");
        my ($q,$q1,$q2,$q3)=("","","","");
        if ($input->{'kw1'} ne "" ){
            $q1=$input->{'sfield1'} . ":(" . $input->{'kw1'} . ") ";
        }
        if ($input->{'kw2'} ne "" ){
            $q2 .=$input->{'sfield2'} . ":(" . $input->{'kw2'} . ") ";
        }
        if ($input->{'kw3'} ne "" ){
            $q3 .=$input->{'sfield3'} . ":(" . $input->{'kw3'} . ")";
        }
        $q = $q1;
        if ($q2 ne "" && $q3 ne ""){
            $q .= uc($input->{'cfield1'}) . " (" . $q2 .  uc($input->{'cfield2'}) ." ". $q3 . ")";
        }
        elsif ($q2 ne "" ){
            $q .= uc($input->{'cfield1'}) . " ". $q2;
        }
        $luceneQuery .= "&q=$q";
    }
    else { #simple search
        if ($sField eq "0"){
            if ($sExctMatch && $sExctMatch eq "1"){
                $luceneQuery .= "&q=eq_anywhere_exct:(\"$sTerm\")";
            }else{
                $luceneQuery .= "&q=eq_anywhere:($sTerm)";
            }
        }
        else{
            if ($sExctMatch && $sExctMatch eq "1"){
                $luceneQuery .= "&q=". $sField ."_exct:(\"" . $sTerm ."\")";
            }else{
                if ($notContain && $notContain eq '1') {
                    $luceneQuery .= "&q=!$sField:($sTerm)";
                }
                else{
                    $luceneQuery .= "&q=$sField:($sTerm)";
                }
            }
        }
    }
    if (defined $building && ($building ne "" || $building ne '0' || $building!=0)){
        $luceneQuery .= " AND 18:($building)";
    }
    $luceneQuery .= "&start=" . $offset . "&rows=" . $pSize;
    my $sortCond = $sortFieldMap->{$sortAttr};
    if ($sortDir eq "1"){
        $sortDir = "asc";
    }
    else{
        $sortDir = "desc";
    }
    $sortCond =~ s/<sortDir>/$sortDir/g;
    $luceneQuery .= "&sort=$sortCond";
    $luceneQuery .= "&wt=json";

    return "$luceneQuery";
}


sub eq_slr_searchJson {
    my $this = shift;
    my $dbh     = $this->{'dbh'};
    my ($params)= @_;
    my ($hits,@result) = (0,());
    if (!defined $params->{'lQuery'} || $params->{'lQuery'} eq ''){
        return {hits=>0,recordList=>undef};
    }
    my($sHost,$sPort,$sDatabase,$db_name) = $this->eq_getSolrSrvInfo();
    #my $url="http://$sHost:$sPort/solr/$sDatabase/select?" . $params->{'lQuery'} ;
    my $url="http://$sHost:$sPort/solr/$db_name/select?" . $params->{'lQuery'} ;
    my $data = _querySolr($url);
    my $result = decode_json($data);
    if ($params->{'displayStyle'} eq "linear" || $params->{'groupBy'} eq "barcode"){
        $hits = $result->{'grouped'}->{'eq_barcode'}->{'matches'} ;
    }
    else{
        $hits = $result->{'grouped'}->{'rid'}->{'ngroups'} ;
    }
    my $facetList = getFacetListJson($result);
    my $fieldMap = {};
    my $recList = getRecordFieldsJson($dbh,$result,$fieldMap,$params->{'displayStyle'});
    return {hits=>$hits,recordList=>$recList,facetList=>$facetList};
}

sub eq_slr_buildQuery_recordList_json {

    my $this = shift;
    my ($input) = @_;

    my $luceneQuery ="fq=db:equipment";
    my $sTerm       = $input->{'kw'};
    my $sField      = $input->{'sfield'};
    my $sExctMatch  = $input->{'exactmatch'} || $input->{'exactMatch'};
    my $sortAttr    = $input->{'sortAttr'};
    my $sortDir     = $input->{'sortOrder'};
    my $offset      = $input->{'offset'};
    my $searchByCat = $input->{'searchByCat'};
    my $catCode     = $input->{'cat'};
    my $building    = $input->{'bldList'} ;
    my $ridList     = $input->{'ridList'};
    my $bcList      = $input->{'bcList'};
    my $pNum        = $input->{'pNum'} || $input->{'pNo'};
    my $pSize       = $input->{'pSize'};
    my $op          = $input->{'op'};
    my ($catSearch,$simpleSearch,$advancedSearch) = (0,0,0);
    $catSearch = ($searchByCat  && $searchByCat > 0)? 1: 0;
    $simpleSearch = ($input->{'kw'} && $input->{'kw'} ne "") ? 1:0;
    $advancedSearch = ($input->{'kw1'} ne "" || $input->{'kw2'} ne "" || $input->{'kw3'} ne "")?1:0;

    if ($catSearch == 1) {
        if ($catCode && $catCode ne ""){
            $luceneQuery .= "&q=category:($catCode)";
        }
        else{
            $luceneQuery .= "&q=category:\*";
        }
    }
    elsif ($advancedSearch == 1){
        my ($sField1,$sField2,$sField3)= ("","","");
        my $q="";
        if ($input->{'kw1'} ne "" ){
            $q=$input->{'sfield1'} . ":(" . $input->{'kw1'} . ") ";
        }
        if ($input->{'kw2'} ne "" ){
            $q .= uc($input->{'cfield1'}) . " ";
            $q .=$input->{'sfield2'} . ": (" . $input->{'kw2'} . ") ";
        }
        if ($input->{'kw3'} ne "" ){
            $q .= uc($input->{'cfield2'}) . " ";
            $q .=$input->{'sfield3'} . ":(" . $input->{'kw3'} . ")";
        }
        $luceneQuery .= "&q=$q";
    }
    else { #simple search
        if ($sField eq "0" || $sField == 0){
            if ($sExctMatch && $sExctMatch eq "1"){
                $luceneQuery .= "&q=eq_anywhere_exct:(\"$sTerm\")";
            }else{
                $luceneQuery .= "&q=eq_anywhere:($sTerm)";
            }
        }
        else{
            if ($sExctMatch && $sExctMatch eq "1"){
                $luceneQuery .= "&q=". $sField ."_exct:(\"" . $sTerm ."\")";
            }else{
                $luceneQuery .= "&q=$sField:($sTerm)";
            }
        }
    }
    if (defined $building && ($building ne "" || $building ne '0' || $building!=0)){
        $luceneQuery .= " AND 18:('$building')";
    }
    if ($ridList eq "all"){
        my $sortCond = $sortFieldMap->{$sortAttr};
        if ($sortDir eq "1"){
            $sortDir = "asc";
        }
        else{
            $sortDir = "desc";
        }
        $sortCond =~ s/<sortDir>/$sortDir/g;
        $luceneQuery .= "&sort=$sortCond";
    }
	  elsif (ref($ridList) eq 'ARRAY'){
		my $ridStr="";
		foreach my $rid (@{$ridList}){
            $ridStr .= " OR " if ($ridStr ne "" && $rid>0);
            $ridStr .= $rid && $rid>0 ?" rid:$rid ":"";
        }
        if ($ridStr) {
          $luceneQuery = "&q=(".$ridStr .")";
        }
	  }
    else{
        my @rids = split(/,/,$ridList);
        my $ridStr="";
        my $bcStr="";

        foreach my $id(@rids){
            $ridStr .= " OR " if $ridStr ne "";
            $ridStr .= "(rid:$id AND eq_name:[* TO *] )";
        }
        if ($ridStr) {
          $luceneQuery = "&q=(".$ridStr .")";
        }
        #my @bcList = split(/,/,$bcList);
        foreach my $id(@$bcList){
            $bcStr .= " OR " if $bcStr ne "";
            #$bcStr .= "(eq_barcode:'$id' AND eq_name:[* TO *] )";
            $bcStr .= "eq_barcode:$id ";
        }
        if ($bcStr) {
          $luceneQuery = "&q=(".$bcStr .")";
        }
    }
    $luceneQuery .= "&fl=*";
    $luceneQuery .= "&wt=json";
    if ($pNum && $pNum>0 && $pSize && int($pSize)>0 ) {
      #$luceneQuery .= "&start=" . ($pNum-1) * $pSize . "&row=".$pSize;
    }
    else {
      $luceneQuery .= "&rows=2147483647";
    }
    return $luceneQuery
}

sub eq_getSolrSrvInfo {
    my $sHost   = Opals::Context->config('sHost');
    my $sPort   = Opals::Context->config('sPort');
    my $sDatabase = Opals::Context->config('zDatabase');
    my $db_name = Opals::Context->config('db_name');
    return ($sHost,$sPort,$sDatabase,$db_name);
}

sub _querySolr{
    my($url)=@_;
    my $timeout = 600;
    my $userAgent = LWP::UserAgent->new(agent   => 'OPALS', timeout=>$timeout);
    my $request = HTTP::Request->new(GET => $url); 
    my $response = $userAgent->request($request );
    return $response->content;
}

sub getSearchHits {
    my ($xml) = @_;
    my $hits=0;
    if($xml =~ m/<result name="response" numFound="([\d]+)" start="([\d]+)"\/*>/){
        $hits=$1;
    }
    else{
        if($xml =~ m/<int name="matches">([\d]+)<\/int>/){
            $hits=$1;
        }
    }
    return $hits;
}

sub getGroupFound {
    my ($xml) = @_;
    my $hits=0;
    #if($xml =~ m/<int name="matches">([\d]+)<\/int>/){
    #    $hits=$1;
    #}
    if($xml =~ m/<int name="ngroups">([\d]+)<\/int>/){
        $hits=$1;
    }
    return $hits;
}

sub getRecordIdList {
    my ($xml) = @_;
    my @rId = ();
    my $tmpXml = $xml;
    my $recXml="";
    while($tmpXml =~ m/<doc>(.*?)<\/doc>(.*)/s){
        $recXml=$1;
        $tmpXml=$2;
        if($recXml =~ m/<str name="rid">(.*?)<\/str>/s){
            push @rId, $1;
        }
    }
    return \@rId;
}
sub getRecordIdListJson {
    my ($data,$display) = @_;
    my @rId = ();
    my $grpRId = ($display eq "linear" )?$data->{'grouped'}->{'eq_barcode'}->{'groups'}:$data->{'grouped'}->{'rid'}->{'groups'};
    foreach my $d(@{$grpRId}){
      push @rId, $d->{'groupValue'};
    }
    return \@rId;
}

sub getFacetList {
    my ($xml) = @_;
    my $tmpXml;
    my $facetList=[];
    while (my ($k,$v) = each %{$facetFieldMap}){
        $tmpXml = $xml;
        if($tmpXml =~ /<lst name="$v">(.*?)<\/lst>/){
            $tmpXml = $1;
            my $fList=[];
            while($tmpXml =~ m/<int name="(.*?)">(.*?)<\/int>(.*)/s){
                my $fc=$1;
                $tmpXml = $3;
                push @$fList, {field=>$1,value=>$2} if ($fc ne '');
            }
            push @$facetList, {field=>$v,facetList=>$fList} ;   
        }
    }
    return $facetList;
}
sub getFacetListJson {
    my ($data) = @_;
    my $tmp;
    my $facetList=[];
    my $factet_fields = $data->{'facet_counts'}->{'facet_fields'};
    foreach my $ff (keys % {$factet_fields}){
      my %h = @{$factet_fields->{$ff}};
      my $fList = [];
      while (my ($k,$v) = each %h){ #remove key empty
        push @$fList, {field=>$k,value=>$v}  if ($k ne "");
      }
      push @$facetList, {field=>$ff,facetList=>$fList} ;
    }
    return $facetList;
}

sub getRsCategoryFacet {
    my ($xml) = @_;
    my $tmpXml = $xml;
    my $categoryFactList = [];
    if($tmpXml =~ /<lst name="category_facet">(.*?)<\/lst>/){
        $tmpXml = $1;
        while($tmpXml =~ m/<int name="(.*?)">(.*?)<\/int>(.*)/s){
            push @$categoryFactList, {
                field=>$1,
                value=>$2
            };
            $tmpXml = $3;
        }
    }
    return $categoryFactList;
}

sub getRsBuildingFacet {
    my ($xml) = @_;
    my $tmpXml = $xml;
    my $buildingFactList = [];
    if($tmpXml =~ /<lst name="building_facet">(.*?)<\/lst>/){
        $tmpXml = $1;
        while($tmpXml =~ m/<int name="(.*?)">(.*?)<\/int>(.*)/s){
            push @$buildingFactList, {
                field=>$1,
                value=>$2
            };
            $tmpXml = $3;
        }
    }
    return $buildingFactList;
}

sub getRecordFields {
    my ($dbh, $xml,$fieldMap) = @_;
    my $fieldMap = {
        rid             =>  "rid",
        eq_name         =>  "eq_name",
        category_facet  =>  "category",
        1               =>  "manufacturer",
        3               =>  "model",
        eq_barcode      =>  "barcode",
        5               =>  "serialNumber",
        38               => "status",
        11               => "location",
        41               => "assignedLName",
        46               => "cartNumber",
    };
    my $showOnSearchFieldMap = getShowOnSearchFields($dbh);
    $showOnSearchFieldMap->{'rid'}      = "rid";
    $showOnSearchFieldMap->{'eq_name'}  = "eq_name";
    $showOnSearchFieldMap->{'category_facet'}  =  "category";
    $showOnSearchFieldMap->{'eq_barcode'}  =  "barcode";
    $showOnSearchFieldMap->{'typeId'}  =  "typeId";
    my $category =  getCategoryList($dbh);
    my @recordList = ();
    my $record;
    my $tmpXml = $xml;
    my $recXml;
    my $fieldType="str|float|int|date";

    while ( $tmpXml =~ m/<doc>(.*?)<\/doc>(.*)/s ) {
        $recXml=$1;
        $tmpXml=$2;
        $record=undef;
        #foreach my $field(keys %{$fieldMap}){
        foreach my $field(keys %{$showOnSearchFieldMap}){
            if ($recXml =~ m/(<$fieldType) name="$field">(.*?)<\/($fieldType)>/s){
                $record->{$showOnSearchFieldMap->{$field}}= escapeXMLChars($2);
            }
            elsif($recXml =~ m/<arr name="$field">(.*?)<\/arr>/s){
                my $arrXml=$1;
                while($arrXml =~ m/<($fieldType)>(.*?)<\/($fieldType)>(.*)/s){
                    #push @{$record->{$fieldMap->{$field}}},{item=>$category->{$2}}  if ($1 eq $3);
                    push @{$record->{$showOnSearchFieldMap->{$field}}},{item=>$category->{$2}}  if ($1 eq $3);
                    $arrXml=$4;
                }
            }
        }
        push @recordList, $record if(defined $record);
    }
    return \@recordList;
}
sub getRecordFieldsJson {
    my ($dbh, $data,$fieldMap,$type) = @_;
    #my $showOnSearchFieldMap = getShowOnSearchFields($dbh);
    my $showOnSearchFieldMap = getFieldList($dbh,{});
    $showOnSearchFieldMap->{'rid'}      = "rid";
    $showOnSearchFieldMap->{'eq_name'}  = "eq_name";
    $showOnSearchFieldMap->{'category_facet'}  =  "category";
    $showOnSearchFieldMap->{'eq_barcode'}  =  "barcode";
    $showOnSearchFieldMap->{'typeId'}  =  "typeId";
    my $category =  getCategoryList($dbh);
    my @recordList = ();
    my $record;
    #my $rs =($type eq 'linear')?$data->{'grouped'}->{'eq_barcode'}->{'groups'}:$data->{'grouped'}->{'rid'}->{'groups'};
    my $rs;
      $rs = $data->{'grouped'}->{'rid'}->{'groups'} || $data->{'grouped'}->{'eq_barcode'}->{'groups'} ;
    #foreach my $rec (@{$data->{'grouped'}->{'rid'}->{'groups'}}){
    foreach my $rec (@{$rs}){
      $record=undef;
      foreach my $field(keys %{$showOnSearchFieldMap}){
        foreach my $f(@{$rec->{'doclist'}->{'docs'}}){
          if ($field eq "category_facet"){
            $f->{$field} = $f->{$field} || [];
            $record->{'category'} = [] ;
            foreach my $c (@{$f->{$field}}){
              push @{$record->{'category'}},{item=>$c};
            }
          }
          $record->{$field} = $f->{$field} || "";
        }
      }
      push @recordList, $record if(defined $record);
    }
    return \@recordList;
}    

sub getBuildingList {
    my ($dbh) = @_;
    my $sql= <<_SQL_;
select code,name,address,city,state from eq_locationDirectory order by code;
_SQL_

    my $sth = $dbh->prepare($sql);
    my $list;
    $sth->execute();
    while (my $b = $sth->fetchrow_hashref()) {
        if (!$list->{$b->{'code'}}){
            $list->{$b->{'code'}}->{'code'} = $b->{'code'};
            $list->{$b->{'code'}}->{'name'} = $b->{'name'};
            $list->{$b->{'code'}}->{'address'} = $b->{'adddress'};
            $list->{$b->{'code'}}->{'city'} = $b->{'city'};
            $list->{$b->{'code'}}->{'state'} = $b->{'state'};
        }
    }
    return $list;
}

sub getCategoryList {
    my ($dbh) = @_;
    my $sth = $dbh->prepare("select id,name from eq_category");
    my $list;
    $sth->execute();
    while (my $b = $sth->fetchrow_hashref()) {
        $list->{$b->{'id'}} = $b->{'name'};
    }
    return $list;
}

sub escapeXMLChars {

    my ($str) = @_;
    $str =~ s/&amp;/&/sg;
    $str =~ s/&lt;/</sg;
    $str =~ s/&gt;/>/sg;
    $str =~ s/&quot;/"/sg;
    $str =~ s/&apos;/'/sg;
    return $str;
}

sub getFieldList {
    my ($dbh,$p) = @_;
    my $sql = "select id,name, showOnSearch from eq_def ";
    if ($p && $p->{'showOnSearch'} ==1){
      $sql .= " where showOnSearch=1";
    }
    my $sth = $dbh->prepare("select id,name, showOnSearch from eq_def" );
    my $list;
    $sth->execute();
    while (my $f = $sth->fetchrow_hashref()) {
        $list->{$f->{'id'}} = lc($f->{'id'});
    }
    return $list;
}

sub getShowOnSearchFields {

    my ($dbh) = @_;
    my $sth = $dbh->prepare("select id,name, showOnSearch from eq_def where showOnSearch=1");
    my $list;
    $sth->execute();
    while (my $f = $sth->fetchrow_hashref()) {
        $list->{$f->{'id'}} = lc($f->{'id'});
    }
    return $list;
}
#test for SesssionHdl
sub eq_slr_buildSrchQuery_SessionHdl {
    my $this = shift;
    my ($input) = @_;
    my $luceneQuery ="fq=db:equipment";
    $luceneQuery .= "&group.ngroups=true&group=true&group.field=rid";
    my $sTerm       = $input->{'kw'};
    my $sField      = $input->{'sfield'};
    my $sExctMatch  = $input->{'exactmatch'};
    my $sortAttr    = $input->{'sortAttr'};
    my $sortDir     = $input->{'sortOrder'};
    my $offset      = $input->{'offset'};
    my $pSize       = $input->{'pSize'};
    my $searchByCat = $input->{'searchByCat'};
    my $catCode     = $input->{'cat'};
    my $building    = $input->{'bldList'};
    my $notContain  = $input->{'notContain'};
    
    my ($catSearch,$simpleSearch,$advancedSearch) = (0,0,0);
    $catSearch = ($searchByCat  && $searchByCat > 0)? 1: 0;
    $simpleSearch = ($input->{'kw'} && $input->{'kw'} ne "") ? 1:0;
    #$advancedSearch = ($input->{'kw1'} ne "" || $input->{'kw2'} ne "" || $input->{'kw3'} ne "")?1:0;

    if ($catSearch == 1) {
        if ($catCode && $catCode > 0){
            $luceneQuery .= "&q=category:($catCode)";
        }
        else{
            $luceneQuery .= "&q=category:\*";
        }
    }
    else { 
        if ($sField eq "0"){
            if ($sExctMatch && $sExctMatch eq "1"){
                $luceneQuery .= "&q=eq_anywhere_exct:(\"$sTerm\")";
            }else{
                $luceneQuery .= "&q=eq_anywhere:($sTerm)";
            }
        }
        else{
            if ($sExctMatch && $sExctMatch eq "1"){
                $luceneQuery .= "&q=". $sField ."_exct:(\"" . $sTerm ."\")";
            }else{
                if ($notContain && $notContain eq '1') {
                    $luceneQuery .= "&q=!$sField:($sTerm)";
                }
                else{
                    $luceneQuery .= "&q=$sField:($sTerm)";
                }
            }
        }
    }
    if (defined $building && ($building ne "" || $building ne '0' || $building!=0)){
        $luceneQuery .= " AND 18:($building)";
    }
    $luceneQuery .= "&fl=rid,eq_name,eq_barcode";
    $luceneQuery .= "&start=" . $offset . "&rows=" . $pSize;

    my $sortCond = $sortFieldMap->{$sortAttr};
    if ($sortDir eq "1"){
        $sortDir = "asc";
    }
    else{
        $sortDir = "desc";
    }
        $sortCond =~ s/<sortDir>/$sortDir/g;
    $luceneQuery .= "&sort=$sortCond";

    return "$luceneQuery";

}

sub eq_slr_search_SessionHdl {

    my $this = shift;
    my $dbh     = $this->{'dbh'};
    my ($params)= @_;
    my ($hits,@result) = (0,());
    if (!defined $params->{'lQuery'} || $params->{'lQuery'} eq ''){
        return {hits=>0,recordList=>undef};
    }
    my($sHost,$sPort,$sDatabase,$db_name) = $this->eq_getSolrSrvInfo();
    my $url="http://$sHost:$sPort/solr/$sDatabase/select?" . $params->{'lQuery'} ;
    #my $url="http://$sHost:$sPort/solr/$sDatabase/$db_name/select?" . $params->{'lQuery'} ;

    my $xmlStr = _querySolr($url);
    if ($params->{'displayStyle'} eq "linear"){
        $hits = getSearchHits($xmlStr);
    }
    else{
        $hits = getGroupFound($xmlStr);
    }
    my $fieldMap = {};
    #my $recList = getRecordFields_SessionHdl($dbh,$xmlStr,$fieldMap);
    my $recList = getRecordFields($dbh,$xmlStr,$fieldMap);
    return {hits=>$hits,recordList=>$recList};
}

sub getRecordFields_SessionHdl {

    my ($dbh, $xml,$fieldMap) = @_;
    my $showOnSearchFieldMap;
    $showOnSearchFieldMap->{'rid'}      = "rid";
    $showOnSearchFieldMap->{'eq_name'}  = "eq_name";
    $showOnSearchFieldMap->{'eq_barcode'}  =  "barcode";
    my $category =  getCategoryList($dbh);

    my @recordList = ();
    my $record;
    my $tmpXml = $xml;
    my $recXml;
    my $fieldType="str|float|int|date";
    while ( $tmpXml =~ m/<doc>(.*?)<\/doc>(.*)/s ) {
        $recXml=$1;
        $tmpXml=$2;
        $record=undef;
        #foreach my $field(keys %{$fieldMap}){
        foreach my $field(keys %{$showOnSearchFieldMap}){
            if ($recXml =~ m/(<$fieldType) name="$field">(.*?)<\/($fieldType)>/s){
                $record->{$showOnSearchFieldMap->{$field}}=$2;
            }
            elsif($recXml =~ m/<arr name="$field">(.*?)<\/arr>/s){
                my $arrXml=$1;
                while($arrXml =~ m/<($fieldType)>(.*?)<\/($fieldType)>(.*)/s){
                    push @{$record->{$showOnSearchFieldMap->{$field}}},{item=>$category->{$2}}  if ($1 eq $3);
                    $arrXml=$4;
                }
            }
        }
        push @recordList, $record if(defined $record);
    }
    return \@recordList;
}

=item

sub eq_slr_search_bk {
    my $this = shift;
    my $dbh     = $this->{'dbh'};
    my ($params)= @_;
    my ($hits,@result) = (0,());
    if (!defined $params->{'lQuery'} || $params->{'lQuery'} eq ''){
        return {hits=>0,recordList=>undef};
    }
    my($sHost,$sPort,$sDatabase,$db_name) = $this->eq_getSolrSrvInfo();
    my $url="http://$sHost:$sPort/solr/$sDatabase/select?" . $params->{'lQuery'} ;
    #my $url="http://$sHost:$sPort/solr/$sDatabase/$db_name/select?" . $params->{'lQuery'} ;
    my $xmlStr = _querySolr($url);
    if ($params->{'displayStyle'} eq "linear"){
        $hits = getSearchHits($xmlStr);
    }
    else{
        $hits = getGroupFound($xmlStr);
    }
    my $rIdList = getRecordIdList($xmlStr);
    my $facetList = getFacetList($xmlStr);
    my $fieldMap = {};
    my $recList = getRecordFields($dbh,$xmlStr,$fieldMap);
    return {hits=>$hits,recordList=>$recList,facetList=>$facetList};
}
=cut

#end test for SesssionHdl
#
#
