#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

#include "shared.h"

int EXIT_CODE = 0;

int main() {
  int fd;
  calc_data *data;

  fd = open(SF_NAME, O_CREAT | O_RDWR, 0666);
  if (fd == -1) {
    err(EXIT_FAILURE, "open", __LINE__ - 1);
    goto exit;
  }

  if (ftruncate(fd, SF_SIZE) == -1) {
    err(EXIT_FAILURE, "ftruncate", __LINE__ - 1);
    goto fd_close;
  }

  data = (calc_data *)mmap(NULL, SF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
                           fd, 0);
  if (data == MAP_FAILED) {
    err(EXIT_FAILURE, "mmap", __LINE__ - 1);
    goto fd_close;
  }

  while (!(data->ready_flags & 1))
    spin("Waiting for numbers", 250);
  printf("\rNumbers are '%.2f' and '%.2f'.\n", data->num1, data->num2);

  while (!(data->ready_flags & 2))
    spin("Waiting for operation", 250);
  printf("\rOperation is '%c'.       \n", data->operation);

  printf("All data is collected. Proceed to computation? (Y/n): ");

  switch (getchar()) {
  case 'n':
    return 0;
  default:
    break;
  }

  double result = 0;

  switch (data->operation) {
  case '+':
    result = data->num1 + data->num2;
    break;
  case '-':
    result = data->num1 - data->num2;
    break;
  case '*':
    result = data->num1 * data->num2;
    break;
  case '/':
    if (data->num2 != 0) {
      result = data->num1 / data->num2;
    } else {
      fprintf(stderr, "Division by zero is not allowed!\n");
      goto munmap;
    }
    break;
  default:
    fprintf(stderr, "Unknown operation: %c\n", data->operation);
  }

  printf("Result: %.2f %c %.2f = %.2f\n", data->num1, data->operation,
         data->num2, result);

munmap:
  munmap(data, SF_SIZE);

fd_close:
  close(fd);

  unlink(SF_NAME);
exit:
  return EXIT_CODE;
}
