#include <u.h>
#include <libc.h>
#include <bio.h>

char choice[2048];
char index[] = "/sys/games/lib/fortunes.index";
char fortunes[] = "/sys/games/lib/fortunes";

void
main(int argc, char *argv[])
{
       int i;
       long offs;
       uchar off[4];
       int ix, nix;
       int newindex, oldindex;
       char *p;
       Dir *fbuf, *ixbuf;
       Biobuf *f, g;

       newindex = 0;
       oldindex = 0;
       ix = offs = 0;
       if((f=Bopen(argc>1?argv[1]:fortunes, OREAD)) == 0){
               print("Misfortune!\n");
               exits("misfortune");
       }
       ixbuf = nil;
       if(argc == 1){
               ix = open(index, OREAD);
               if(ix>=0){
                       ixbuf = dirfstat(ix);
                       fbuf = dirfstat(Bfildes(f));
                       if(ixbuf == nil || fbuf == nil){
                               print("Misfortune?\n");
                               exits("misfortune");
                       }
                       if(ixbuf->length < sizeof(offs)){
                               /* someone else is rewriting the index */
                               goto NoIndex;
                       }
                       oldindex = 1;
                       if(fbuf->mtime > ixbuf->mtime){
                               nix = create(index, OWRITE, 0666);
                               if(nix >= 0){
                                       close(ix);
                                       ix = nix;
                                       newindex = 1;
                                       oldindex = 0;
                               }
                       }
               }else{
                       ix = create(index, OWRITE, 0666);
                       if(ix >= 0)
                               newindex = 1;
               }
       }
       if(oldindex){
               seek(ix, ntruerand(ixbuf->length/sizeof(offs))*sizeof(offs), 0);
               read(ix, off, sizeof(off));
               Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0);
               p = Brdline(f, '\n');
               if(p){
                       p[Blinelen(f)-1] = 0;
                       strncpy(choice, p, sizeof(choice)-1);
               }else
                       strcpy(choice, "Misfortune!");
       }else{
NoIndex:
               Binit(&g, ix, 1);
               srand(truerand());
               for(i=1;;i++){
                       if(newindex)
                               offs = Boffset(f);
                       p = Brdline(f, '\n');
                       if(p == 0)
                               break;
                       p[Blinelen(f)-1] = 0;
                       if(newindex){
                               off[0] = offs;
                               off[1] = offs>>8;
                               off[2] = offs>>16;
                               off[3] = offs>>24;
                               Bwrite(&g, off, sizeof(off));
                       }
                       if(nrand(i)==0)
                               strncpy(choice, p, sizeof(choice)-1);
               }
       }
       print("%s\n", choice);
       exits(0);
}