# File: Quotegrabs_Hashtable.pm
# Author: pragma_
#
# Purpose: Hashtable backend for storing and retreiving quotegrabs

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

package Plugins::Quotegrabs::Quotegrabs_Hashtable;

use warnings;
use strict;

use feature 'unicode_strings';

use HTML::Entities;
use Time::Duration;
use Time::HiRes qw(gettimeofday);
use Getopt::Long qw(GetOptionsFromString);

use POSIX qw(strftime);

sub new {
  if (ref($_[1]) eq 'HASH') {
    Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference");
  }

  my ($class, %conf) = @_;

  my $self = bless {}, $class;
  $self->initialize(%conf);
  return $self;
}

sub initialize {
  my ($self, %conf) = @_;

  $self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference in " . __FILE__);
  $self->{filename} = delete $conf{filename};
  $self->{quotegrabs} = [];
}

sub begin {
  my $self = shift;
  $self->load_quotegrabs;
}

sub end {
}

sub load_quotegrabs {
  my $self = shift;
  my $filename;

  if (@_) { $filename = shift; } else { $filename = $self->{filename}; }
  return if not defined $filename;

  $self->{pbot}->{logger}->log("Loading quotegrabs from $filename ...\n");

  open(FILE, "< $filename") or die "Couldn't open $filename: $!\n";
  my @contents = <FILE>;
  close(FILE);

  my $i = 0;
  foreach my $line (@contents) {
    chomp $line;
    $i++;
    my ($nick, $channel, $timestamp, $grabbed_by, $text) = split(/\s+/, $line, 5);
    if (not defined $nick || not defined $channel || not defined $timestamp
       || not defined $grabbed_by || not defined $text) {
      die "Syntax error around line $i of $filename\n";
    }

    my $quotegrab = {};
    $quotegrab->{nick} = $nick;
    $quotegrab->{channel} = $channel;
    $quotegrab->{timestamp} = $timestamp;
    $quotegrab->{grabbed_by} = $grabbed_by;
    $quotegrab->{text} = $text;
    $quotegrab->{id} = $i + 1;
    push @{ $self->{quotegrabs} }, $quotegrab;
  }
  $self->{pbot}->{logger}->log("  $i quotegrabs loaded.\n");
  $self->{pbot}->{logger}->log("Done.\n");
}

sub save_quotegrabs {
  my $self = shift;
  my $filename;

  if (@_) { $filename = shift; } else { $filename = $self->{filename}; }
  return if not defined $filename;

  open(FILE, "> $filename") or die "Couldn't open $filename: $!\n";

  for(my $i = 0; $i <= $#{ $self->{quotegrabs} }; $i++) {
    my $quotegrab = $self->{quotegrabs}[$i];
    next if $quotegrab->{timestamp} == 0;
    print FILE "$quotegrab->{nick} $quotegrab->{channel} $quotegrab->{timestamp} $quotegrab->{grabbed_by} $quotegrab->{text}\n";
  }

  close(FILE);
}

sub add_quotegrab {
  my ($self, $quotegrab) = @_;

  push @{ $self->{quotegrabs} }, $quotegrab;
  $self->save_quotegrabs();
  return $#{ $self->{quotegrabs} } + 1;
}

sub delete_quotegrab {
  my ($self, $id) = @_;

  if ($id < 1 || $id > $#{ $self->{quotegrabs} } + 1) {
    return undef;
  }

  splice @{ $self->{quotegrabs} }, $id - 1, 1;

  for(my $i = $id - 1; $i <= $#{ $self->{quotegrabs} }; $i++ ) {
    $self->{quotegrabs}[$i]->{id}--;
  }

  $self->save_quotegrabs();
}

sub get_quotegrab {
  my ($self, $id) = @_;

  if ($id < 1 || $id > $#{ $self->{quotegrabs} } + 1) {
    return undef;
  }

  return $self->{quotegrabs}[$id - 1];
}

sub get_random_quotegrab {
  my ($self, $nick, $channel, $text) = @_;

  $nick = '.*' if not defined $nick;
  $channel = '.*' if not defined $channel;
  $text = '.*' if not defined $text;

  my @quotes;

  eval {
    for(my $i = 0; $i <= $#{ $self->{quotegrabs} }; $i++) {
      my $hash = $self->{quotegrabs}[$i];
      if ($hash->{channel} =~ /$channel/i && $hash->{nick} =~ /$nick/i && $hash->{text} =~ /$text/i) {
        $hash->{id} = $i + 1;
        push @quotes, $hash;
      }
    }
  };

  if ($@) {
    $self->{pbot}->{logger}->log("Error in show_random_quotegrab parameters: $@\n");
    return undef;
  }

  if ($#quotes < 0) {
    return undef;
  }

  return $quotes[int rand($#quotes + 1)];
}

sub get_all_quotegrabs {
  my $self = shift;
  return $self->{quotegrabs};
}

1;