# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.

package Bugzilla::Config;

use 5.10.1;
use strict;
use warnings;

use parent qw(Exporter);
use autodie qw(:default);

use Bugzilla::Constants;
use Bugzilla::Hook;
use Bugzilla::Util qw(trick_taint);

use JSON::XS;
use File::Slurp;
use File::Temp;
use File::Basename;

# Don't export localvars by default - people should have to explicitly
# ask for it, as a (probably futile) attempt to stop code using it
# when it shouldn't
%Bugzilla::Config::EXPORT_TAGS =
  (
   admin => [qw(update_params SetParam write_params)],
  );
Exporter::export_ok_tags('admin');

# INITIALISATION CODE
# Perl throws a warning if we use bz_locations() directly after do.
our %params;
# Load in the param definitions
sub _load_params {
    my $panels = param_panels();
    my %hook_panels;
    foreach my $panel (keys %$panels) {
        my $module = $panels->{$panel};
        eval("require $module") || die $@;
        my @new_param_list = $module->get_param_list();
        $hook_panels{lc($panel)} = { params => \@new_param_list };
    }
    # This hook is also called in editparams.cgi. This call here is required
    # to make SetParam work.
    Bugzilla::Hook::process('config_modify_panels', 
                            { panels => \%hook_panels });

    foreach my $panel (keys %hook_panels) {
        foreach my $item (@{$hook_panels{$panel}->{params}}) {
            $params{$item->{'name'}} = $item;
        }
    }
}
# END INIT CODE

# Subroutines go here

sub param_panels {
    my $param_panels = {};
    my $libpath = bz_locations()->{'libpath'};
    foreach my $item ((glob "$libpath/Bugzilla/Config/*.pm")) {
        $item =~ m#/([^/]+)\.pm$#;
        my $module = $1;
        $param_panels->{$module} = "Bugzilla::Config::$module" unless $module eq 'Common';
    }
    # Now check for any hooked params
    Bugzilla::Hook::process('config_add_panels', 
                            { panel_modules => $param_panels });
    return $param_panels;
}

sub SetParam {
    my ($name, $value) = @_;

    _load_params unless %params;
    die "Unknown param $name" unless (exists $params{$name});

    my $entry = $params{$name};

    # sanity check the value

    # XXX - This runs the checks. Which would be good, except that
    # check_shadowdb creates the database as a side effect, and so the
    # checker fails the second time around...
    if ($name ne 'shadowdb' && exists $entry->{'checker'}) {
        my $err = $entry->{'checker'}->($value, $entry);
        die "Param $name is not valid: $err" unless $err eq '';
    }

    Bugzilla->params->{$name} = $value;
}

sub update_params {
    my ($params) = @_;
    my $answer = Bugzilla->installation_answers;
    my $datadir = bz_locations()->{'datadir'};
    my $param;

    # If the old data/params file using Data::Dumper output still exists,
    # read it. It will be deleted once the parameters are stored in the new
    # data/params.json file.
    my $old_file = "$datadir/params";

    if (-e $old_file) {
        require Safe;
        my $s = new Safe;

        $s->rdo($old_file);
        die "Error reading $old_file: $!" if $!;
        die "Error evaluating $old_file: $@" if $@;

        # Now read the param back out from the sandbox.
        $param = \%{ $s->varglob('param') };
    }
    else {
        # Rename params.js to params.json if checksetup.pl
        # was executed with an earlier version of this change
        rename "$old_file.js", "$old_file.json"
            if -e "$old_file.js" && !-e "$old_file.json";

        # Read the new data/params.json file.
        $param = read_param_file();
    }

    my %new_params;

    # If we didn't return any param values, then this is a new installation.
    my $new_install = !(keys %$param);

    # --- UPDATE OLD PARAMS ---

    # Change from usebrowserinfo to defaultplatform/defaultopsys combo
    if (exists $param->{'usebrowserinfo'}) {
        if (!$param->{'usebrowserinfo'}) {
            if (!exists $param->{'defaultplatform'}) {
                $new_params{'defaultplatform'} = 'Other';
            }
            if (!exists $param->{'defaultopsys'}) {
                $new_params{'defaultopsys'} = 'Other';
            }
        }
    }

    # Change from a boolean for quips to multi-state
    if (exists $param->{'usequip'} && !exists $param->{'enablequips'}) {
        $new_params{'enablequips'} = $param->{'usequip'} ? 'on' : 'off';
    }

    # Change from old product groups to controls for group_control_map
    # 2002-10-14 bug 147275 bugreport@peshkin.net
    if (exists $param->{'usebuggroups'} && 
        !exists $param->{'makeproductgroups'}) 
    {
        $new_params{'makeproductgroups'} = $param->{'usebuggroups'};
    }

    # Modularise auth code
    if (exists $param->{'useLDAP'} && !exists $param->{'loginmethod'}) {
        $new_params{'loginmethod'} = $param->{'useLDAP'} ? "LDAP" : "DB";
    }

    # set verify method to whatever loginmethod was
    if (exists $param->{'loginmethod'} 
        && !exists $param->{'user_verify_class'}) 
    {
        $new_params{'user_verify_class'} = $param->{'loginmethod'};
    }

    # Remove quip-display control from parameters
    # and give it to users via User Settings (Bug 41972)
    if ( exists $param->{'enablequips'} 
         && !exists $param->{'quip_list_entry_control'}) 
    {
        my $new_value;
        ($param->{'enablequips'} eq 'on')       && do {$new_value = 'open';};
        ($param->{'enablequips'} eq 'approved') && do {$new_value = 'moderated';};
        ($param->{'enablequips'} eq 'frozen')   && do {$new_value = 'closed';};
        ($param->{'enablequips'} eq 'off')      && do {$new_value = 'closed';};
        $new_params{'quip_list_entry_control'} = $new_value;
    }

    # Old mail_delivery_method choices contained no uppercase characters
    my $mta = $param->{'mail_delivery_method'};
    if ($mta) {
        if ($mta !~ /[A-Z]/) {
            my %translation = (
                'sendmail' => 'Sendmail',
                'smtp'     => 'SMTP',
                'qmail'    => 'Qmail',
                'testfile' => 'Test',
                'none'     => 'None');
            $param->{'mail_delivery_method'} = $translation{$mta};
        }
        # This will force the parameter to be reset to its default value.
        delete $param->{'mail_delivery_method'} if $param->{'mail_delivery_method'} eq 'Qmail';
    }

    # Convert the old "ssl" parameter to the new "ssl_redirect" parameter.
    # Both "authenticated sessions" and "always" turn on "ssl_redirect"
    # when upgrading.
    if (exists $param->{'ssl'} and $param->{'ssl'} ne 'never') {
        $new_params{'ssl_redirect'} = 1;
    }

    # "specific_search_allow_empty_words" has been renamed to "search_allow_no_criteria".
    if (exists $param->{'specific_search_allow_empty_words'}) {
        $new_params{'search_allow_no_criteria'} = $param->{'specific_search_allow_empty_words'};
    }

    # --- DEFAULTS FOR NEW PARAMS ---

    _load_params unless %params;
    foreach my $name (keys %params) {
        my $item = $params{$name};
        unless (exists $param->{$name}) {
            print "New parameter: $name\n" unless $new_install;
            if (exists $new_params{$name}) {
                $param->{$name} = $new_params{$name};
            }
            elsif (exists $answer->{$name}) {
                $param->{$name} = $answer->{$name};
            }
            else {
                $param->{$name} = $item->{'default'};
            }
        }
    }

    $param->{'utf8'} = 1 if $new_install;

    # Bug 452525: OR based groups are on by default for new installations
    $param->{'or_groups'} = 1 if $new_install;

    # --- REMOVE OLD PARAMS ---

    my %oldparams;
    # Remove any old params
    foreach my $item (keys %$param) {
        if (!exists $params{$item}) {
            $oldparams{$item} = delete $param->{$item};
        }
    }

    # Write any old parameters to old-params.txt
    my $old_param_file = "$datadir/old-params.txt";
    if (scalar(keys %oldparams)) {
        my $op_file = new IO::File($old_param_file, '>>', 0600)
          || die "Couldn't create $old_param_file: $!";

        print "The following parameters are no longer used in Bugzilla,",
              " and so have been\nmoved from your parameters file into",
              " $old_param_file:\n";

        my $comma = "";
        foreach my $item (keys %oldparams) {
            print $op_file "\n\n$item:\n" . $oldparams{$item} . "\n";
            print "${comma}$item";
            $comma = ", ";
        }
        print "\n";
        $op_file->close;
    }

    write_params($param);

    if (-e $old_file) {
        unlink $old_file;
        say "$old_file has been converted into $old_file.json, using the JSON format.";
    }

    # Return deleted params and values so that checksetup.pl has a chance
    # to convert old params to new data.
    return %oldparams;
}

sub write_params {
    my ($param_data) = @_;
    $param_data ||= Bugzilla->params;
    my $param_file = bz_locations()->{'datadir'} . '/params.json';

    my $json_data = JSON::XS->new->canonical->pretty->encode($param_data);
    write_file($param_file, { binmode => ':utf8', atomic => 1 }, \$json_data);

    # It's not common to edit parameters and loading
    # Bugzilla::Install::Filesystem is slow.
    require Bugzilla::Install::Filesystem;
    Bugzilla::Install::Filesystem::fix_file_permissions($param_file);

    # And now we have to reset the params cache so that Bugzilla will re-read
    # them.
    delete Bugzilla->request_cache->{params};
}

sub read_param_file {
    my %params;
    my $file = bz_locations()->{'datadir'} . '/params.json';

    if (-e $file) {
        my $data;
        read_file($file, binmode => ':utf8', buf_ref => \$data);

        # If params.json has been manually edited and e.g. some quotes are
        # missing, we don't want JSON::XS to leak the content of the file
        # to all users in its error message, so we have to eval'uate it.
        %params = eval { %{JSON::XS->new->decode($data)} };
        if ($@) {
            my $error_msg = (basename($0) eq 'checksetup.pl') ?
                $@ : 'run checksetup.pl to see the details.';
            die "Error parsing $file: $error_msg";
        }
        # JSON::XS doesn't detaint data for us.
        foreach my $key (keys %params) {
            if (ref($params{$key}) eq "ARRAY") {
                foreach my $item (@{$params{$key}}) {
                    trick_taint($item);
                }
            } else {
                trick_taint($params{$key}) if defined $params{$key};
            }
        }
    }
    elsif ($ENV{'SERVER_SOFTWARE'}) {
       # We're in a CGI, but the params file doesn't exist. We can't
       # Template Toolkit, or even install_string, since checksetup
       # might not have thrown an error. Bugzilla::CGI->new
       # hasn't even been called yet, so we manually use CGI::Carp here
       # so that the user sees the error.
       require CGI::Carp;
       CGI::Carp->import('fatalsToBrowser');
       die "The $file file does not exist."
           . ' You probably need to run checksetup.pl.',
    }
    return \%params;
}

1;

__END__

=head1 NAME

Bugzilla::Config - Configuration parameters for Bugzilla

=head1 SYNOPSIS

  # Administration functions
  use Bugzilla::Config qw(:admin);

  update_params();
  SetParam($param, $value);
  write_params();

=head1 DESCRIPTION

This package contains ways to access Bugzilla configuration parameters.

=head1 FUNCTIONS

=head2 Parameters

Parameters can be set, retrieved, and updated.

=over 4

=item C<SetParam($name, $value)>

Sets the param named $name to $value. Values are checked using the checker
function for the given param if one exists.

=item C<update_params()>

Updates the parameters, by transitioning old params to new formats, setting
defaults for new params, and removing obsolete ones. Used by F<checksetup.pl>
in the process of an installation or upgrade.

Prints out information about what it's doing, if it makes any changes.

May prompt the user for input, if certain required parameters are not
specified.

=item C<write_params($params)>

Description: Writes the parameters to disk.

Params:      C<$params> (optional) - A hashref to write to the disk
               instead of C<Bugzilla-E<gt>params>. Used only by
               C<update_params>.

Returns:     nothing

=item C<read_param_file()>

Description: Most callers should never need this. This is used
             by C<Bugzilla-E<gt>params> to directly read C<$datadir/params.json>
             and load it into memory. Use C<Bugzilla-E<gt>params> instead.

Params:      none

Returns:     A hashref containing the current params in C<$datadir/params.json>.

=item C<param_panels()>

=back
