#!/usr/bin/perl
#
# DW::Controller::Search::Multisearch
#
# Conversion of LJ's multisearch.bml, used for handling redirects
# from sitewide search bar (LJ::Widget::Search).
#
# Also includes handler for /tools/search which simply renders
# the search widget on a separate page.
#
# Authors:
#      Jen Griffin <kareila@livejournal.com>
#
# Copyright (c) 2011-2016 by Dreamwidth Studios, LLC.
#
# This program is free software; you may redistribute it and/or modify it under
# the same terms as Perl itself. For a copy of the license, please reference
# 'perldoc perlartistic' or 'perldoc perlgpl'.
#

package DW::Controller::Search::Multisearch;

use strict;

use DW::Routing;
use DW::Template;
use DW::Controller;
use Locale::Codes::Country;

DW::Routing->register_string( '/multisearch',  \&multisearch_handler, app => 1 );
DW::Routing->register_string( '/tools/search', \&toolsearch_handler,  app => 1 );

sub multisearch_handler {
    my $r    = DW::Request->get;
    my $args = $r->did_post ? $r->post_args : $r->get_args;

    my $type   = lc( $args->{'type'}   || '' );
    my $q      = lc( $args->{'q'}      || '' );
    my $output = lc( $args->{'output'} || '' );

    my ( $ok, $rv ) = controller( anonymous => 1 );
    return $rv unless $ok;

    # functions for handling various call types
    my ( $f_nav, $f_user, $f_int, $f_email, $f_faq, $f_region );

    $f_nav = sub {

        # Some special shortcuts used for easy navigation
        return $r->redirect("$LJ::SITEROOT/support/faqbrowse?faqid=$1&view=full")
            if $q =~ /^faq (\d+)$/;
        return $r->redirect("$LJ::SITEROOT/support/see_request?id=$2")
            if $q =~ /^req(uest)? (\d+)$/;

        if ( $q =~ m!(.+)/(pics|full)! ) {
            if ( my $u = LJ::load_user_or_identity($1) ) {
                return $r->redirect( $u->profile_url( full => 1 ) )
                    if $2 eq "full";
                return $r->redirect( $u->allpics_base )
                    if $2 eq "pics";
            }
        }

        if ( $type eq "nav_and_user" ) {
            if ( my $u = LJ::load_user_or_identity($q) ) {
                return $r->redirect( $u->profile_url() );
            }
        }

        my $eq = LJ::ehtml($q);
        return error_ml( '/multisearch.tt.errorpage.nomatch.nav', { query => $eq } );
    };

    $f_user = sub {
        my $user = $q;
        $user =~ s!\@$LJ::USER_DOMAIN!!;
        $user =~ s!/(\w+)!!;
        my $what = defined $1 ? $1 : '';

        $user =~ s/-/_/g;
        $user =~ s/[^\w]//g;

        return $r->redirect("$LJ::SITEROOT/random") unless $user;

        my $u = LJ::load_user($user);
        return $r->redirect("$LJ::SITEROOT/profile?user=$user") unless $u;

        return $r->redirect( $u->allpics_base ) if $what eq "pics";

        my $url = $u->profile_url;
        $url .= "?mode=full" if $what eq 'full';
        return $r->redirect($url);
    };

    $f_int = sub {
        return error_ml('/multisearch.tt.errorpage.nointerest') unless $q;
        return $r->redirect( "$LJ::SITEROOT/interests?int=" . LJ::eurl($q) );
    };

    $f_email = sub {
        return error_ml('/multisearch.tt.errorpage.noaddress') unless $q;

        my $dbr = LJ::get_db_reader();
        my $uid = $dbr->selectrow_array(
            qq{
            SELECT userid FROM user WHERE journaltype='P' AND statusvis='V'
            AND allow_contactshow='Y' AND email=? LIMIT 1 }, undef, $q
        );

        # if not in the user table, try the email table
        $uid ||= $dbr->selectrow_array(
            qq{
            SELECT e.userid FROM user u, email e WHERE e.email=?
            AND e.userid=u.userid AND u.journaltype='P' AND u.statusvis='V'
            AND u.allow_contactshow='Y' LIMIT 1 }, undef, $q
        );

        if ( my $u = LJ::load_userid($uid) ) {
            my $show = $u->opt_whatemailshow;
            if ( $show eq "A" || $show eq "B" ) {
                return $r->redirect( $u->profile_url );
            }
        }
        return error_ml('/multisearch.tt.errorpage.nomatch');
    };

    $f_region = sub {
        $q = LJ::trim($q);
        my @parts = split /\s*,\s*/, $q;
        if ( @parts == 0 || @parts > 3 ) {
            $rv->{type} = 'region';
            return DW::Template->render_template( 'multisearch.tt', $rv );
        }

        my $ctc = $parts[-1];
        my $country;
        if ( length($ctc) > 2 ) {

            # Must be country name
            $country = uc country2code($ctc);
        }
        else {
            # Likely country code or invalid
            $country = uc country_code2code( $ctc, LOCALE_CODE_ALPHA_2, LOCALE_CODE_ALPHA_2 );
            $country ||= uc country2code($ctc);    # 2-letter country name??
        }

        my ( $state, $city );

        if ($country) {
            pop @parts;
            if ( @parts == 1 ) {
                $state = $parts[0];
            }
            else {
                ( $city, $state ) = @parts;
            }

        }
        else {
            $country = "US";

            if ( @parts == 1 ) {
                $city = $parts[0];
            }
            else {
                ( $city, $state ) = @parts;
            }
        }

        ( $city, $state, $country ) = map { LJ::eurl($_) } ( $city, $state, $country );
        return $r->redirect( "$LJ::SITEROOT/directorysearch?s_loc=1"
                . "&loc_cn=$country&loc_st=$state&loc_ci=$city"
                . "&opt_sort=ut&opt_format=pics&opt_pagesize=50" );
    };

    $f_faq = sub {
        return error_ml('/multisearch.tt.errorpage.nofaq') unless $q;
        return $r->redirect( "$LJ::SITEROOT/support/faqsearch?q=" . LJ::eurl($q) );
    };

    # set up dispatch table
    my $dispatch = {
        nav_and_user => $f_nav,
        user         => $f_user,
        int          => $f_int,
        email        => $f_email,
        region       => $f_region,
        faq          => $f_faq,
    };

    return $dispatch->{$type}->() if exists $dispatch->{$type};

    # No type specified - redirect them somewhere useful.
    return $r->redirect("$LJ::SITEROOT/tools/search");
}

sub toolsearch_handler {
    my ( $ok, $rv ) = controller( anonymous => 1 );
    return $rv unless $ok;

    $rv->{widget}   = LJ::Widget::Search->render;
    $rv->{sitename} = $LJ::SITENAMESHORT;
    return DW::Template->render_template( 'tools/search.tt', $rv );
}

1;
