/* Seat Graffiti 1-2
   by Jonathan Rothwell */

/* INCLUDES */
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <string.h>

/* PROTOTYPES */
void splash(void);
void anykey(void);
void newline(int lines);
float countest(int cycles);
float bubbletest(int data);
float iowtest(int bytes);
float iortest(int bytes);
void DSHandler(int type);

int main()
{
    char buffer[128];
    long int numbuf;
    float intsps, sortsps, byteswps, bytesrps;
    FILE *output;
    
    splash(); //splash screen
    
    /* INTEGER TEST */
    puts("How many cycles for the integer test? Recommended 10,000,000, enter 0 for this.");
    scanf("%i",&numbuf);
    fflush(stdin); //swap this for fpurge(stdin); on *nixes
    newline(1);
    if(numbuf == 0)
    {
               intsps = countest(10000000);
    }
    else
    {
        intsps = countest(numbuf);
    }
    
    numbuf = 0;
    
    puts("How many data for the sort test? Recommended 100,000, enter 0 for this.");
    scanf("%i",&numbuf);
    fflush(stdin);
    newline(1);
    if(numbuf == 0)
    {
              sortsps = bubbletest(100000);
    }
    else
    {
        sortsps = bubbletest(numbuf);
    }
    
    numbuf = 0;
    
    puts("How many bytes for disk i/o test? Recommended 536870912 for 512MiB, enter 0 for this.");
    scanf("%i",&numbuf);
    fflush(stdin);
    newline(1);
    if(numbuf == 0){
              byteswps = iowtest(536870912);
              bytesrps = iortest(536870912);
    }
    else
    {
        byteswps = iowtest(numbuf);
        bytesrps = iowtest(numbuf);
    }
    puts("Deleting swap file...");
    unlink("sgraff.swap");
    puts("Done.");
    newline(2);
    anykey();
    puts("Where to save results (hit ENTER for stdout, ./ for working directory)?");
    scanf("%s",&buffer);
    if(strcmp(buffer,"") == 0){
                             puts("FINAL RESULTS");
                             puts("~~~~~~~~~~~~~");
                             printf("Integer increment\t%f\tcalculations per second\n",intsps);
                             printf("Bubble sort test\t%f\tsorts per second\n",sortsps);
                             printf("Disk write test\t\t%f\tbytes per second\n",byteswps);
                             printf("Disk read test\t\t%f\tbytes per second\n",bytesrps);
    }
    else
    {
        printf("Writing to %s, please wait...",buffer);
        output = fopen(buffer,"w");
        if(output == NULL){
                  puts("FINAL RESULTS");
                  puts("~~~~~~~~~~~~~");
                  printf("Integer increment\t%f\tcalculations per second\n",intsps);
                  printf("Bubble sort test\t%f\tsorts per second\n",sortsps);
                  printf("Disk write test\t\t%f\tbytes per second\n",byteswps);
                  printf("Disk read test\t\t%f\tbytes per second\n",bytesrps);
                  DSHandler(2);
        }
        else
        {
            fprintf(output,"TEST RESULTS FOR THIS COMPUTER\n");
            fprintf(output,"Generated by Seat Graffiti by Jonathan Rothwell\n");
            fprintf(output,"\n\n");
            fprintf(output,"FINAL RESULTS\n");
            fprintf(output,"~~~~~~~~~~~~~\n");
            fprintf(output,"Integer increment\t%f\tcalculations per second\n",intsps);
            fprintf(output,"Bubble sort test\t%f\tsorts per second\n",sortsps);
            fprintf(output,"Disk write test\t\t%f\tbytes per second\n",byteswps);
            fprintf(output,"Disk read test\t\t%f\tbytes per second\n",bytesrps);
            fprintf(output,"This file written at %i.\n",time(NULL));
            }
    }
    fflush(stdin);                     
 

    
    anykey();
    
    return 0;
}

void splash(void)
{
     puts("Welcome to Seat Graffiti 1-2");
     puts("by Jonathan Rothwell");
     newline(2);
}

void anykey(void)
{
     puts("Press any key to continue.");
     getchar();
}

void newline(int lines)
{
     int i = 0;
     
     for(i=0;i<lines;i++)
     {
                         putchar('\n');
     }
}                   

float countest(int cycles)
{
    int i = 0;
    int starttime, endtime, difftime;
    float cps;
    
    
    puts("Now starting integer count test");
    starttime = time(NULL);
    for(i=0;i<cycles;i++)
    {
                         printf("Cycle %i of %i\r",i+1,cycles);
    }
    endtime = time(NULL);
    difftime = endtime - starttime;
    cps = cycles / difftime;
    printf("Cycle %i of %i. Done.\n",i,cycles);
    printf("Completed in %i seconds, producing a mean of %f calculations/second.\n",difftime,cps);
    
    newline(2);
    return(cps);
}

float bubbletest(int data)
{
      int starttime, endtime, difftime;
      float sps;
      int r[data];
      int c,a,b,temp;
      long int sorts;
      
      srand((unsigned)time(NULL));
      
      for(c=0;c<data;c++)
      {
                         r[c] = rand() % 1000000000 +1;
      }
      puts("Array built. Now sorting.");
      starttime = time(NULL);
      
      for(a=0;a<data-1;a++)
                           for(b=a+1;b<data;b++)
                                                if(r[a] > r [b])
                                                {
                                                        temp = r[b];
                                                        r[b] = r[a];
                                                        r[a] = temp;
                                                        sorts++;
                                                }
                                                ;
      endtime = time(NULL);
      puts("Done.");
      difftime = endtime - starttime;
      sps = sorts / difftime;
      sps = -sps;
      printf("Completed %i sorts in %i seconds, producing a mean of %f sorts per second.\n",-sorts,difftime,sps);
      return(sps);
}

float iowtest(int bytes)
{
      int starttime, endtime, difftime;
      FILE *swapfile;
      char c;
      int i = 0;
      float bytess;
      
      swapfile = fopen("sgraff.swap","w");
      puts("File is open... now testing, if this fails, will hand to DSHandler");
      if(!swapfile) DSHandler(1);
      
      c = '0';
      
      starttime = time(NULL);
      
      for(i=0;i<=bytes;i++)
      {
                          fprintf(swapfile,"0");
                          printf("Writing byte %i of %i.\r",i,bytes);
      }
      endtime = time(NULL);
      newline(1);
      printf("Done.\n");
      difftime = endtime - starttime;
      bytess = bytes / difftime;
      printf("Wrote %ib to sgraff.swap in %i seconds, producing a mean of %f bytes per second\n",bytes,difftime,bytess);
      fclose(swapfile);
      newline(1);
      return(bytess);
}

float iortest(int bytes)
{
      int starttime, endtime, difftime;
      FILE *swapfile;
      char c;
      int i = 0;
      float bytess;
      
      swapfile = fopen("sgraff.swap","r");
      puts("File is open... now testing, if this fails, will hand to DSHandler");
      if(!swapfile) DSHandler(1);
      
      c = '0';
      
      starttime = time(NULL);
      
      for(i=0;i<bytes;i++)
      {
                          c = fgetc(swapfile);
                          printf("Reading byte %i (%c) of %i.\r",i,c,bytes);
      }
      endtime = time(NULL);
      newline(1);
      printf("Done.\n");
      difftime = endtime - starttime;
      bytess = bytes / difftime;
      printf("Read %ib from sgraff.swap in %i seconds, producing a mean of %f bytes per second\n",bytes,difftime,bytess);
      fclose(swapfile);
      newline(1);
      return(bytess);
}
     
void DSHandler(int type)
{
     puts("            (__)");
     puts("            (oo)");
     puts("    /-oooooo-\\/ ");
     puts("   * ooooooooo  ");
     puts("  ooooooooooooo ");
     puts(" ooooooooooooooooo");
     puts("~~~~~~~~~~~~~~~~~~~");
     newline(1);
     puts("Oh, dear.");
     printf("Seat Graffiti returned error %i. Good bye.\n\n",type);
     abort();
}

