#!/usr/bin/perl -w

use strict;
use warnings;

our $VERSION = 3.1;

=head1 NAME

createMetadataDB

=head1 DESCRIPTION

Creates the metadata database for the TL1 collector.

=cut

use Getopt::Long;
use Config::General;
use DBI;
use Carp;

=head2 usage()

A function to print out the command-line options understood by this script.

=cut

sub usage {
    print "$0: Initialize a Status database\n";
    print "  --config: The database.conf file containing all the parameters\n";
    print "  --type: The database type: 'sqlite' or 'mysql'\n";
    print "  --prefix: The prefix of the tables to create. defaults to 'ps_'\n";
    print "  If SQLite is chosen, you can use these arguments\n";
    print "  --file: The database file to use\n";
    print "  If MySQL is chosen, you can use these arguments\n";
    print "  --name: The database to use\n";
    print "  --host: The database host to use\n";
    print "  --port: The database port to use\n";
    print "  --username: The database username to use\n";
    print "  --password: The database password to use\n";
    return;
}

my $sqlite_create_metadata_ports_table = <<EOQ
CREATE TABLE IF NOT EXISTS TABLEPREFIX_metadata_ports (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  urn VARCHAR(255) not null,
  host_name VARCHAR(32) not null,
  port_name VARCHAR(32) not null,
  direction VARCHAR(5),
  capacity INTEGER,
  description VARCHAR(255),
  data_type   VARCHAR(255) not null,
  rrd_file    VARCHAR(255) not null,
 unique (data_type, urn, host_name, port_name, direction));
EOQ
    ;

my $mysql_create_metadata_ports_table = <<EOQ
CREATE TABLE IF NOT EXISTS TABLEPREFIX_metadata_ports (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  urn VARCHAR(255) not null,
  host_name VARCHAR(32) not null,
  port_name VARCHAR(32) not null,
  direction VARCHAR(5),
  capacity INTEGER,
  description VARCHAR(255),
  data_type   VARCHAR(255) not null,
  rrd_file    VARCHAR(255) not null,
 unique (data_type, urn, host_name, port_name, direction));
EOQ
    ;

my $CONFIG_FILE;
my $DEBUGFLAG;
my $HELP;
my $LOGGER_CONF;
my $NEW_TOPOLOGY;
my $DB_TYPE;
my $DB_PREFIX;
my $DB_HOST;
my $DB_PORT;
my $DB_NAME;
my $DB_FILE;
my $DB_USERNAME;
my $DB_PASSWORD;

my ( $status, $res, $res2 );

$status = GetOptions(
    'config=s'   => \$CONFIG_FILE,
    'type=s'     => \$DB_TYPE,
    'prefix=s'   => \$DB_PREFIX,
    'file=s'     => \$DB_FILE,
    'name=s'     => \$DB_NAME,
    'host=s'     => \$DB_HOST,
    'port=s'     => \$DB_PORT,
    'username=s' => \$DB_USERNAME,
    'password=s' => \$DB_PASSWORD,
);

if ( $CONFIG_FILE ) {
    my $config = new Config::General( $CONFIG_FILE );
    my %conf   = $config->getall;

    $DB_TYPE   = $conf{metadata_db_type}   if ( $conf{metadata_db_type} );
    $DB_PREFIX = $conf{metadata_db_prefix} if ( $conf{metadata_db_prefix} );

    $DB_FILE = $conf{metadata_db_file} if ( $conf{metadata_db_file} );

    $DB_NAME     = $conf{metadata_db_name}     if ( $conf{metadata_db_name} );
    $DB_HOST     = $conf{metadata_db_host}     if ( $conf{metadata_db_host} );
    $DB_PORT     = $conf{metadata_db_port}     if ( $conf{metadata_db_port} );
    $DB_USERNAME = $conf{metadata_db_username} if ( $conf{metadata_db_username} );
    $DB_PASSWORD = $conf{metadata_db_password} if ( $conf{metadata_db_password} );
}

unless ( $DB_TYPE ) {
    print "No database type specified\n";
    usage();
    exit( -1 );
}

$DB_TYPE = lc( $DB_TYPE );

if ( $DB_TYPE ne "sqlite" and $DB_TYPE ne "mysql" ) {
    print "Invalid database type specified. Must be either 'mysql' or 'sqlite'\n";
    usage();
    exit( -1 );
}

$DB_PREFIX = 'ps' unless $DB_PREFIX;

if ( $DB_TYPE eq "sqlite" ) {
    unless ( $DB_FILE ) {
        print "Need to specify a database file\n";
        usage();
        exit( -1 );
    }

    my $dbi_string = "DBI:SQLite:dbname=" . $DB_FILE;

    $sqlite_create_metadata_ports_table =~ s/TABLEPREFIX/$DB_PREFIX/gm;

    my ( $sth );

    my $dbh = DBI->connect( $dbi_string );
    $sth = $dbh->prepare( $sqlite_create_metadata_ports_table ) or croak "Couldn't prepare statement: " . $dbh->errstr;
    $sth->execute();
}
elsif ( $DB_TYPE eq "mysql" ) {
    my $dbi_string = "dbi:mysql";

    unless ( $DB_NAME ) {
        print "Need to specify a database name\n";
        usage();
        exit( -1 );
    }

    $mysql_create_metadata_ports_table =~ s/TABLEPREFIX/$DB_PREFIX/gm;

    $dbi_string .= ":host=" . $DB_HOST if $DB_HOST;
    $dbi_string .= ":port=" . $DB_PORT if $DB_PORT;

    my $dbh = DBI->connect( $dbi_string );
    my $sth = $dbh->prepare( "CREATE DATABASE $DB_NAME" ) or croak "Couldn't prepare statement: " . $dbh->errstr;
    $sth->execute();
    $sth = $dbh->prepare( "USE $DB_NAME" ) or croak "Couldn't prepare statement: " . $dbh->errstr;
    $sth->execute();
    $sth = $dbh->prepare( $mysql_create_metadata_ports_table ) or croak "Couldn't prepare statement: " . $dbh->errstr;
    $sth->execute();

    if ($DB_USERNAME) {
        my $sql = "GRANT ALL PRIVILEGES ON *.* TO '$DB_USERNAME'\@'%'";
	if ($DB_PASSWORD) {
	    $sql .= "IDENTIFIED BY '".$DB_PASSWORD."'";
	}
	$sql .= ";";
	$sth = $dbh->prepare( $sql ) or croak "Couldn't prepare statement: " . $dbh->errstr;
	$sth->execute();
    }
}

__END__

=head1 SEE ALSO

L<Getopt::Long>, L<DBI>, L<Carp>

To join the 'perfSONAR Users' mailing list, please visit:

  https://mail.internet2.edu/wws/info/perfsonar-user

The perfSONAR-PS subversion repository is located at:

  http://anonsvn.internet2.edu/svn/perfSONAR-PS/trunk

Questions and comments can be directed to the author, or the mailing list.
Bugs, feature requests, and improvements can be directed here:

  http://code.google.com/p/perfsonar-ps/issues/list

=head1 VERSION

$Id$

=head1 AUTHOR

Aarobn Brown, aaron@internet2.edu
Jason Zurawski, zurawski@internet2.edu

=head1 LICENSE

You should have received a copy of the Internet2 Intellectual Property Framework
along with this software.  If not, see
<http://www.internet2.edu/membership/ip.html>

=head1 COPYRIGHT

Copyright (c) 2008-2009, Internet2

All rights reserved.

=cut
