#!/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

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

=head1 LICENSE

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=head1 COPYRIGHT

Copyright (c) 2008-2009, Internet2

All rights reserved.

=cut
