#include "kernel/types.h"
#include "user/user.h"

#define WORK 100000000000
#define MAXTIME 200

/*

This testcase checks whether a process scheduled once runs for 10 ticks or not.
The next testcase will not be checked if you fail this testcase.

*/

void
test()
{
  int id;
  for (id = 0; id < 10 && fork(); id++)
    ;

  if (id == 10) {
    return;
  }

  int numTickChanges = 0, currUpTime = 0, prevUpTime = 0;
  int upTimes[200];

  int baseUpTime = uptime();

  while (1) {
    currUpTime = uptime();

    if (currUpTime != prevUpTime && currUpTime - baseUpTime < MAXTIME) {
      upTimes[numTickChanges] = currUpTime;
      prevUpTime = currUpTime;
      numTickChanges++;
    }

    if (currUpTime > MAXTIME + baseUpTime)
      break;
  }

  int numExecutions = 0;
  int totalTicksExecutedFor = 0;
  int i = 0;

  while (i < numTickChanges) {
    int minimum = upTimes[i];
    int maximum = upTimes[i];
    int add = 0;
    int counter = 1;

    while (i + 1 < numTickChanges && upTimes[i + 1] == upTimes[i] + 1 &&
           counter < 10) {
      if (upTimes[i + 1] == baseUpTime + MAXTIME - 1) {
        add = 0;
        break;
      }

      maximum = upTimes[i + 1];
      i++;
      add = 1;
      counter++;
    }

    if (add) {
      totalTicksExecutedFor += maximum - minimum + 1;
      numExecutions++;
    }

    i++;
  }

  if (numExecutions)
    exit(totalTicksExecutedFor / numExecutions);

  exit(0);
}

int
main()
{
  printf("================================\n");
  printf("-----RUNNING TESTCASE-SLICE-----\n");
  printf("================================\n");

  test();

  int failed = 0;
  int zeroCount = 0;

  for (int i = 0; i < 10; i++) {
    int status;
    int pid = wait(&status);

    if (status != 10 && status != 11 && status != 9) {
      failed = 1;
    }
    if (status == 0)
      zeroCount++;

    printf("[PID %d] executed for an average timeslice of %d\n", pid, status);
  }

  if (failed) {
    printf("==========================\n");
    printf("------TESTCASE FAILED-----\n");
    printf("Average timeslice is not 10\n");
    printf("==========================\n");
  } else if (zeroCount == 10) {
    printf("==========================\n");
    printf("------TESTCASE FAILED-----\n");
    printf("No process executed\n");
    printf("==========================\n");
  } else {
    printf("==========================\n");
    printf("------TESTCASE PASSED-----\n");
    printf("==========================\n");
  }
}
