#!/usr/local/bin/perl

#manages the narcissistic bibliography MIB

#deploy as:
#rocommunity megadweeb 0.0.0.0/0 1.3.6.1.4.1.55030
#rocommunity6 megadweeb 0::/0 1.3.6.1.4.1.55030
#pass_persist .1.3.6.1.4.1.55030.1.1.1 /usr/local/scripts/persistwp.pl


no warnings 'experimental::smartmatch';
#$DEBUG=1;

$place = ".1.3.6.1.4.1.55030.1.1.1";   # TWP mwlbooks OID
#$place = ".1.3.6.1.3.1";                #experimental OID for testing

$|=1; #flush buffer after every print

#maxindex = top legit index value
#increment every time you add a book!
$maxindex=102;

#save the PID file
$PIDFILE="/var/run/pass_persist.pid";
open(PIDFILE, ">$PIDFILE");
print PIDFILE "$$\n";
close(PIDFILE);

#the data, FSM help us
# all arrays start with zero

#column 1: the row index, no data needed

#column 2: the titles, where all goes bad

@titles = (X, "Gatecrasher", "Believe it or Else!",
	   "SLUGS: The Satanic, Loathsome, Unholy Game System (as Greg Donner)",
	   "Gatecrasher 2nd edition",
	   "Women who Run with the Werewolves", "Absolute BSD",
	   "Absolute OpenBSD", "Cisco Routers for the Desperate", "PGP & GPG",
	   "Absolute FreeBSD, 2nd edition",
	   "Cisco Routers for the Desperate, 2nd edition",
	   "Network Flow Analysis", "Horror Library volume 2",
	   "Opening the Eye", "Breaking the Circle", "SSH Mastery",
	   "Vicious Redemption: Five Dark Fantasies", "DNSSEC Mastery",
	   "Sudo Mastery", "Absolute OpenBSD, 2nd ed",
	   "No More Lonesome Blue Rings", "Sticky Supersaturation",
	   "Lavender", "Pax Canina", "Wednesday's Seagulls",
	   "FreeBSD Mastery: Storage Essentials", "Immortal Clay",
	   "Waking Up Yesterday", "Calling Control", "Moonlight's Apples",
	   "Networking for Systems Administrators", "Tarsnap Mastery",
	   "FreeBSD Mastery: ZFS", "Forever Falls",
	   "Spilled Mirovar (Prohibition Orcs 1)", "Whisker Line",
	   "Wifi and Romex", "PAM Mastery",
	   "FreeBSD Mastery: Advanced ZFS", "FreeBSD Mastery: Advanced ZedFS",
	   "Kipuka Blues (Immortal Clay #2)", "Hydrogen Sleets",
	   "Drowned Mirovar (Prohibition Orcs #2)",
	   "Butterfly Stomp Waltz (Beaks #1)",
	   "Earthquake Kitten Kiss (Beaks spin-off)",
	   "Butterfly Stomp (Beaks #0)",
	   "Forced to Talk, Like, With Your Mouth",
	   "FreeBSD Mastery: Specialty Filesystems",
	   "git commit murder", "savaged by systemd",
	   "Httpd and Relayd Mastery", "Ed Mastery",
	   "Ed Mastery, Manly McManface Edition",
	   "SSH Mastery, 2nd edition", "Absolute FreeBSD, 3rd edition",
	   "Bedazzled by Blockchain", "Face Less",
	   "Boundary Shock: Tuesday After Next",
	   "Boundary Shock: Robots, Androids, Cyborgs, Oh My!",
	   "Sudo Mastery, 2nd edition", "FreeBSD Mastery: Jails",
	   "Terrapin Sky Tango (Beaks #2)", "Winner Breaks All",
	   "Boundary Shock: Apocalypse Descending",
	   "Fiction River: Superstitious", "Snot-Nosed Aliens",
	   "An Interpretation of Moles", "SNMP Mastery",
	   "Boundary Shock: Alien Dreams", "The Networknomicon",
           "Cash Flow for Creators", "Boundary Shock: What Might Have Been",
	   "Face The Strange", "Bloody Christmas", "Drinking Heavy Water",
	   "Final Gift", "Woolen Torment", "Drums with Delusions of Godhood",
	   "Uncollected Anthology: Deities", "Drag Air Through Fire",
	   "Aidan Redding Against the Universes", "Fiction River: Chances",
	   "Fiction River: Dark and Deadly Passions", "TLS Mastery",
	   "Only Footnotes", "git sync murder", "The Holiday Spectacular #2",
	   "Boundary Shock: Wandering Monsters", "Fantastic Christmas",
	   "Mysterious Christmas", "Witness November",
	   "Domesticate Your Badgers", "DNSSEC Mastery, 2nd edition",
	   "Letters from ed(1): The FreeBSD Journal Letters column, years 1-3",
	   "Fiction River: Broken Dreams", "Prohibition Orcs", "Frozen Talons",
	   "OpenBSD Mastery: Filesystems", "Devotion and Corrosion",
	   "The Rats' Man's Lackey and the Half Gallon of Christmas Miracle",
	   "The Rats' Man's Lackey and the Delphi Taco", "Apocalypse Moi",
    );

#column 3, year

@years = ( X, 1992, 1993, 1994, 1995, 1995, 2002, 2003, 2004, 2006, 2007,
	   2009, 2010, 2010, 2011, 2011, 2012, 2012, 2013, 2013, 2013,
	   2013, 2013, 2013, 2013, 2013, 2014, 2014, 2014, 2014, 2014,
	   2015, 2015, 2015, 2015, 2015, 2015, 2015, 2016, 2016, 2016,
	   2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2017, 2017,
	   2017, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2019,
	   2019, 2019, 2019, 2019, 2019, 2019, 2019, 2020, 2020, 2020,
	   2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2021,
	   2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021,
	   2021, 2022, 2022, 2022, 2022, 2022, 2022, 2023, 2023, 2023,
	   2023, 2023 );

#column 4, type of book/genre
# 1 = fiction, 2 = nonfiction

@genre = (X, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1, 2, 2, 2,
	  1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2,
	  1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2,
	  2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	  1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1,
	  1, 1 );

#column 5, length
# 1 = full length, 2 = novella, 3 = story, 4 = anthology appearance

@length = (X, 1, 1, 2, 1, 4, 1, 1, 1, 1, 1, 1, 1, 4, 3, 3, 1, 1, 1, 1, 1, 3,
	   3, 3, 3, 3, 1, 1, 3, 3, 3, 1, 1, 1, 2, 3, 3, 3, 1, 1, 1, 1,
	   1, 2, 1, 2, 3, 3, 1, 1, 3, 1, 2, 2, 1, 1, 3, 3, 4, 4, 1, 1,
	   1, 3, 4, 4, 4, 4, 1, 4, 1, 1, 4, 4, 4, 1, 3, 3, 3, 4, 3, 1, 4,
	   4, 1, 2, 1, 4, 4, 4, 4, 3, 1, 1, 2, 4, 1, 1, 1, 1, 3, 2, 1 );


while (<>) {
    if (m!^PING!) {
	print "PONG\n";
	next;
    }

    my $command= $_;
    my $inoid = <>;
    my $returnoid;
    chomp ($command);
    chomp ($inoid);
    my $rawoid = $inoid;
    
    #sanity check, parsing

    #is this our MIB?
    if ($inoid =~ /^$place/) {
	$inoid =~ s/$place\.//;
	print "our OID!\n\n" if $DEBUG;
    }
    else {
	print "not our OID, die die die\n" if $DEBUG;
	print "NONE\n";
	next;
    }

    #make parseable
    ($column,$row,$detritus) = split (/\./,$inoid);

    if ($DEBUG) {
	print "Command is $command\n";
	print "input OID is $inoid\n";
	print "raw OID is $rawoid\n";
	print "converted to $inoid\n";
	print "Column is $column\n";
	print "Row is $row\n";
	print "Detritus is $detritus\n";
    }

#GETNEXT
#valid OIDs are:
#$place.[1-4].1-maxindex.detritus
#$split as $place.$column.$row.$detritus

    if ($command eq "getnext") {

    if ($column == 0) {
	$column=1;
	$row=1;
    }

    else {
	if ($row < $maxindex) {
	    #next OID will be:
	    #$place.$column.$row++
	    $row++;
	}
	else {
	    $column++;
	    $row=1;
	}

	#if the column is over 5, we've reached the end of the MIB
	#	die "Column over 4, DIE DIE DIE\n" unless ($column <= 5);
	unless ($column <= 5) {
	    print "NONE\n";
	    next;
	}
	
    }
    $returnoid = $place.'.'.$column.'.'.$row ;
    print "returnoid is $returnoid\n" if $DEBUG;
    }

    if ($command eq "get") {

	print "Processing GET\n" if $DEBUG;
	
	#  GET requests - check for valid instance
    
	#if $detritus exists: not valid, reject on GET
	if ($detritus) {
	    print "NONE\n";
	    next;
	}
    
	if ($column ~~ [1 .. 5]) {
	    $colvalid=1;
#	    print "column is valid\n" if DEBUG;
	}

	#    if ($row > 0 and $row <= $maxindex) {
        if ($row ~~ [0 .. $maxindex]) {
	    $rowvalid=1;
#	    print "row is valid\n" if $DEBUG;
	}

	if ($colvalid and $rowvalid) {
	    print "Both column and row are valid\n" if $DEBUG;
	    #I could reassemble the requested OID, but that would be work
	    $returnoid=$rawoid; }
	else {
	    print "Row or column is not valid DIE DIE DIE\n" if $DEBUG;
	    print "NONE\n";
	    next;
	}
    }


    #no matter what, we print the returned OID

    print "Script output is:\n" if $DEBUG;
    print $returnoid;

    #index column
    if ($column==1){
	print "\ninteger\n$row\n";
    }

    #titles column
    
    if ($column==2){
	print "\nstring\n$titles[$row]\n";
    }

    #years
    if ($column==3){
	print "\ninteger\n$years[$row]\n";
    }

    #genre column

    if ($column==4){
	print "\ninteger\n$genre[$row]\n";
    }

    #length column

    if ($column==5){
	print "\ninteger\n$length[$row]\n";
    }

}#end of program
