#!/usr/bin/perl -w
#
#  rhrdlibs
#
#  Copyright (C) 2015 Christian Pointner <equinox@helsinki.at>
#
#  This file is part of rhrdlibs.
#
#  rhrdlibs is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Affero General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  any later version.
#
#  rhrdlibs is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Affero General Public License for more details.
#
#  You should have received a copy of the GNU Affero General Public License
#  along with rhrdlibs. If not, see <http://www.gnu.org/licenses/>.
#

use strict;
use lib "../lib/";
use RHRD::rddb;

# this is ridiculous but makes it a little harder to create/remove users...
# if ($> != 0 ) {
#   print STDERR "this must be run as root!\n";
#   exit 1;
# }

sub print_usage
{
  print STDERR "Usage: rd-show list\n" .
               "       rd-show (show|remove) <show-id>\n" .
               "       rd-show add <groupname> <name> <title> <num-carts> <rhythm> <dow> <starttime> <len>\n";
}

sub list
{
  my ($ctx) = @_;

  my @shows = RHRD::rddb::list_shows($ctx);
  if(!defined $shows[0] && defined $shows[1]) {
    print STDERR "$shows[1]: $shows[2]";
    return 1;
  }
  for my $href (@shows) {
    print $href->{'ID'} . ": " . $href->{'TITLE'} . "\n";
  }
  return 0;
}

sub show
{
  my ($ctx, $show_id) = @_;

  my @carts = RHRD::rddb::get_show_carts($ctx, $show_id);
  if(!defined $carts[0] && defined $carts[1]) {
    print STDERR "$carts[1]: $carts[2]\n";
    return 1;
  }
  my ($title, undef, $status, $errorstring) = RHRD::rddb::get_show_title_and_log($ctx, $show_id);
  unless (defined $title) {
    print STDERR "$errorstring\n";
    return 1;
  }
  print $title . ":\n";
  for my $cart (@carts) {
    print " > " . $cart . "\n";
  }
  return 0;
}



sub add__check_arguments
{
  my ($name, $title, $num_carts, $rhythm, $dow, $starttime, $len) = @_;

  if($name !~ m/^[a-zA-Z0-9_]{1,10}$/) {
    print STDERR "name '" . $name . "' contains illegal characters or is too long/short\n";
    print STDERR "  only a-z, A-Z, 0-9 and _ are allowed and the length must be between 1 and 10\n";
    return 1;
  }

  if($num_carts <= 0) {
    print STDERR "num-carts '" . $num_carts . "' must be > 0\n";
    return 1;
  }

  if($rhythm !~ m/^[01]{4}$/ || $rhythm eq '0000') {
    print STDERR "rhythm '" . $rhythm . "' contains illegal characters or is too long/short\n";
    print STDERR "  only 0 or 1 are allowed and, length must be exactly 4 and it must not be '0000'\n";
    return 1;
  }

  if($dow < 1 || $dow > 7) {
    print STDERR "dow '" . $dow . "' is out of range, must be between 1 and 7 (1=Monday, ..., 7=Sunday)\n";
    return 1;
  }

  if($starttime !~ m/^[0-2][0-9][0-5][0-9]$/ || $starttime > 2359) {
    print STDERR "starttime '" . $starttime . "' is not a valid time must be HHMM\n";
    return 1;
  }

  if($len <= 0) {
    print STDERR "len '" . $len . "' must be > 0\n";
    return 1;
  }

  return 0;
}

sub add__get_show_carts
{
  my ($ctx, $groupname, $num_carts) = @_;

  my ($result, $status, $errorstring) = RHRD::rddb::check_group($ctx, $groupname);
  unless(defined $result) {
    print STDERR $status . ": " . $errorstring . "\n";
    return undef;
  }

  my $low_cart = 0;
  if($result) {
    print "   > using existing group '" . $groupname . "'\n";
    $low_cart = add__get_free_group_carts($ctx, $groupname, $num_carts);
  } else {
    print "   > '" . $groupname . "' does not exist - creating it .. ";
    $low_cart = add__create_group($ctx, $groupname);
  }

  return $low_cart;
}

sub add__create_group
{
  my ($ctx, $groupname) = @_;

  my ($cnt, $status, $errorstring) = RHRD::rddb::add_group($ctx, $groupname);
  unless(defined $cnt) {
    print STDERR $status . ": " . $errorstring . "\n";
    return undef;
  }
  print int($cnt) . " rows affected\n";

  (my $low_cart, my $high_cart, $errorstring) = RHRD::rddb::get_shows_next_free_slot($ctx);
  if(!$low_cart) {
    print $high_cart . ": " . $errorstring . "\n";
    return undef;
  }
  print "     using carts " . $low_cart . " - " . $high_cart . " for new group .. ";

  ($cnt, $status, $errorstring) = RHRD::rddb::set_group_carts($ctx, $groupname, $low_cart, $high_cart, 1, 'Y');
  unless(defined $cnt) {
    print STDERR $status . ": " . $errorstring . "\n";
    return undef;
  }
  print int($cnt) . " rows affected\n";

  print "     enabling reports  .. ";
  ($cnt, $status, $errorstring) = RHRD::rddb::set_group_reports($ctx, $groupname, 'Y', 'Y', 'Y');
  unless(defined $cnt) {
    print STDERR $status . ": " . $errorstring . "\n";
    return undef;
  }
  print int($cnt) . " rows affected\n";

  return $low_cart;
}

sub add__get_free_group_carts
{
  my ($ctx, $groupname, $num_carts) = @_;

  my ($low_cart, $high_cart, $type, undef) = RHRD::rddb::get_group_carts($ctx, $groupname);
  unless(defined $low_cart) {
    print STDERR $high_cart . ": " . $type . "\n";
    return undef;
  }

  my @dropboxes = RHRD::rddb::get_dropboxes($ctx, $ctx->{'config'}{'shows'}{'defaultuser'}, $groupname, 'S');
  if(!defined $dropboxes[0]) {
    if(defined $dropboxes[1]) {
      print STDERR "$dropboxes[1]: $dropboxes[2]";
      return undef;
    }
    return $low_cart;
  }

  my @carts = ();
  for my $db (@dropboxes) {
    my @show_carts = RHRD::rddb::get_show_carts($ctx, $db->{'SHOWID'});
    if(!defined $show_carts[0] && defined $show_carts[1]) {
      print STDERR "$show_carts[1]: $show_carts[2]\n";
      return undef;
    }
    @carts = (@carts, @show_carts) if defined($show_carts[0])
  }

  @carts = sort(@carts);
  for my $cart (@carts) {
    last if(($low_cart + $num_carts - 1) < $cart);
    $low_cart += 1;
  }
  if(($low_cart + $num_carts -1) > $high_cart) {
    print STDERR "there are not enough free carts\n";
    return undef;
  }

  return $low_cart;
}

sub add
{
  my ($ctx, $groupname, $name, $title, $num_carts, $rhythm, $dow, $starttime, $len) = @_;

  my $ret = add__check_arguments($name, $title, $num_carts, $rhythm, $dow, $starttime, $len);
  if($ret) {
    return $ret;
  }

  print " * creating show: " . $title . " (" . $name . ") for group '" . $groupname . "'\n";

  my $low_cart = add__get_show_carts($ctx, $groupname, $num_carts);
  return 1 unless defined($low_cart);
  my $high_cart = $low_cart + $num_carts - 1;
  print " * will be using carts: " . $low_cart . " - " . $high_cart . "\n";

  my ($result, $status, $errorstring) = RHRD::rddb::create_show_log($ctx, $name, $low_cart, $high_cart);
  unless(defined $result) {
    print STDERR $status . ": " . $errorstring . "\n";
    return 1;
  }
  print " * created log with name: " . $name . "\n";

  (my $show_id, $status, $errorstring) = RHRD::rddb::create_show_macro_cart($ctx, $name, $title);
  unless(defined $result) {
    print STDERR $status . ": " . $errorstring . "\n";
    return 1;
  }
  print " * created macro cart -> new show-id = " . $show_id . "\n";

  ($result, $status, $errorstring) = RHRD::rddb::create_show_dropbox($ctx, $groupname, $show_id, $rhythm, $dow, $starttime, $len);
  unless(defined $result) {
    print STDERR $status . ": " . $errorstring . "\n";
    return 1;
  }
  print " * created dropbox for show .. " . $result . " rows affected\n";

  print " * finished\n";

  return 0;
}

sub remove
{
  my ($ctx, $show_id) = @_;

  my @results = RHRD::rddb::remove_show($ctx, $show_id);
  if(!defined $results[0] && defined $results[2]) {
    print STDERR "$results[2]\n";
    return 1;
  }
  for my $href (@results) {
    print int($href->{cnt}) . " " . $href->{name} . " deleted\n";
  }
  return 0;
}

my $num_args = $#ARGV + 1;
if($num_args < 1) {
  print_usage();
  exit(1);
}
my $cmd = $ARGV[0];
my $ret = 0;

my ($ctx, $status, $errorstring) = RHRD::rddb::init();
if(defined $ctx) {
  if($cmd eq "list") {
    if($num_args != 1) {
      print_usage();
      $ret = 1;
    } else {
      $ret = list($ctx)
    }
  }
  elsif($cmd eq "show") {
    if($num_args != 2) {
      print_usage();
      $ret = 1;
    } else {
      $ret = show($ctx, $ARGV[1])
    }
  }
  elsif($cmd eq "remove") {
    if($num_args != 2) {
      print_usage();
      $ret = 1;
    } else {
      $ret = remove($ctx, $ARGV[1]);
    }
  }
  elsif($cmd eq "add") {
    if($num_args != 9) {
      print_usage();
      $ret = 1;
    } else {
      $ret = add($ctx, $ARGV[1], $ARGV[2], $ARGV[3], $ARGV[4], $ARGV[5], $ARGV[6], $ARGV[7], $ARGV[8]);
    }
  }
  else {
    print_usage();
    $ret = 1;
  }
  RHRD::rddb::destroy($ctx);
} else {
  print STDERR "$errorstring\n";
  $ret = 1;
}

exit $ret;