#!/usr/bin/perl -w
#
# This script aims at managing the node properties (list, add, delete).
# To set the properties values, use oarnodesettings.
#
# To use the quiet mode, just do something like:
#   echo -e "mysqlroot\nmysqlpassword\n" | oar_property.pl -q -l

use strict;
use warnings;
use OAR::IO;
use OAR::Conf qw(init_conf get_conf is_conf);
use Getopt::Long;
use OAR::Version;
use OAR::Tools;

my $Old_umask = sprintf("%lo", umask());
umask(oct("022"));

# The functions are appended at the end of this file
sub print_usage();
sub check_property_name($);

Getopt::Long::Configure("gnu_getopt");

my ($Help, $List_properties, $Quiet, $Varchar);
my @Add_property;
my @Delete_property;
my @Rename_property;
my $Version;
GetOptions(
    "help|h"     => \$Help,
    "add|a=s"    => \@Add_property,
    "delete|d=s" => \@Delete_property,
    "rename|r=s" => \@Rename_property,
    "list|l"     => \$List_properties,
    "quiet|q"    => \$Quiet,
    "varchar|c"  => \$Varchar,
    "version|V"  => \$Version
  ) or
  exit(1);

if (defined($Version)) {
    print("OAR version: " . OAR::Version::get_version() . "\n");
    exit(0);
}

if ($Help ||
    (($#Add_property < 0) and
        ($#Delete_property < 0) and
        ($#Rename_property < 0) and
        (!defined($List_properties)))
) {
    print_usage();
    exit(1);
}

my $base = OAR::IO::connect();

my $query;

if (defined($List_properties)) {
    my %list = OAR::IO::list_resource_properties_fields($base);
    foreach my $l (keys(%list)) {
        unless (OAR::Tools::check_resource_property($l) == 1) {
            print("$l\n");
        }
    }
}

foreach my $r (@Delete_property) {
    check_property_name($r);

    $base->do("ALTER TABLE resources DROP COLUMN $r") or
      die("DB error: " . $base->errstr . "\n");

    if (!$Quiet) {
        print("Removed property: $r\n");
    }
}

foreach my $a (@Add_property) {
    check_property_name($a);

    my $req;
    if ($Varchar) {
        $req = "ALTER TABLE resources ADD COLUMN $a VARCHAR(255)";
    } else {
        $req = "ALTER TABLE resources ADD COLUMN $a INT";
    }
    $base->do($req) or
      die("DB error: " . $base->errstr . "\n");

    if (!$Quiet) {
        print("Added property: $a\n");
    }
}

foreach my $p (@Rename_property) {
    my ($old_prop, $new_prop);
    if ($p !~ m/^\s*([a-z0-9_]+)\s*,\s*([a-z0-9_]+)\s*$/m) {
        print_usage();
        exit(1);
    }
    $old_prop = $1;
    $new_prop = $2;

    check_property_name($old_prop);
    check_property_name($new_prop);
    if (OAR::IO::get_database_type() eq "Pg") {
        $base->do(" ALTER TABLE resources RENAME $old_prop TO $new_prop") or
          die("DB error: " . $base->errstr . "\n");
    } else {
        my $sth = $base->prepare("SHOW FIELDS FROM resources");
        $sth->execute() or die("DB error: " . $base->errstr . "\n");
        my $type;
        my $field = "";
        while (($field ne $old_prop) and (my @ref = $sth->fetchrow_array())) {
            $field = $ref[0];
            $type  = $ref[1];
        }
        $sth->finish();
        die("Unknown field $old_prop\n") if ($field ne $old_prop);
        $base->do(" ALTER TABLE resources CHANGE $old_prop $new_prop $type");
    }

    $base->do(
        <<EOS
UPDATE resource_logs
SET attribute = \'$new_prop\'
WHERE
    attribute = \'$old_prop\'
EOS
    ) or die("DB error: " . $base->errstr . "\n");

    $base->do(
        <<EOS
UPDATE job_resource_descriptions
SET res_job_resource_type = \'$new_prop\'
WHERE
res_job_resource_type = \'$old_prop\'
EOS
    ) or die("DB error: " . $base->errstr . "\n");

    if (!$Quiet) {
        print("Rename property $old_prop into $new_prop\n");
    }
}

OAR::IO::disconnect($base);

exit(0);

#############################################################################
# FUNCTIONS
#
#Display usage
sub print_usage() {
    print <<EOS;
Usage: $0 [ -l | [ -a [ -V ] | -d ] ] [ -q ] [ -h ]
Manage OAR resource properties
Options:
 -l, --list                             list properties
 -a NAME, --add NAME                    add property
    -c, --varchar                       sql new field of type VARCHAR(255)
                                        (default is integer)
 -d NAME, --delete NAME                 delete property
 -r "OLD_NAME,NEW_NAME", --rename ...   rename property OLD_NAME into NEW_NAME
 -q, --quiet                            quiet mode (no extra output)
 -h, --help                             show this help screen
 -V, --version                          show OAR version
EOS
}

# Check that the given parameter is a valid column name to avoid issues within
# MySQL
sub check_property_name($) {
    my $propertyname = shift;
    if (not $propertyname =~ /^\w+$/) {
        die("Error: '$propertyname' is not a valid property name");
    }
    if (OAR::Tools::check_resource_property($propertyname) == 1) {
        warn("Error: '$propertyname' is a OAR system property and may not be altered\n");
        exit(1);
    }
}
#############################################################################

