#include <stdio.h>
#include <stdlib.h>

// Reads a file and copies its contents to a destination file
int main(int argc, char* argv[]) {
  if (argc != 3) {
    // error if the correct args aren't passed in
    fprintf(stderr, "Usage: %s <source_file> <destination_file>\n", argv[0]);
    return EXIT_FAILURE;
  }

  FILE* input = fopen(argv[1], "r"); // open source file for reading

  if (input == NULL) {
    // can't open input file
    fprintf(stderr, "Can't open source file: %s\n", argv[1]);
    return EXIT_FAILURE;
  }

  FILE* output = fopen(argv[2], "w"); // open dest for writing

  if (output == NULL) {
    // can't open output file
    fprintf(stderr, "Can't open dest file: %s\n", argv[2]);
    return EXIT_FAILURE;
  }

  // buffer to hold characters as we read them from the input
  // file but before we write them to the output file.
  char buffer[100];

  // read the inital amount of butes from the input file
  int num_read = fread(buffer, sizeof(char), 100, input);

  // fread returns 0 when we hit the EOF and there are no more elements to read
  // so stop when num_els is 0
  while(num_read != 0) {
    // write out all characters read in
    //
    // NOTE: must use num_read and not 100 since there may not have been 100
    // characters read. Consider the case we are copying a file that is only
    // 5 characters long
    int num_written = fwrite(buffer, sizeof(char), num_read, output);
    
    // check to make sure all characters read were written
    if (num_written != num_read) {
      fprintf(stderr, "Couldn't write all characters to dest file: %s\n", argv[2]);
      return EXIT_FAILURE;
    }

    // read the next 100 or so characters
    num_read = fread(buffer, sizeof(char), 100, input);
  }

  // technically fread could return 0 on an error, so need to
  // check for that using ferror
  if (ferror(input)) {
    fprintf(stderr, "Couldn't read all characters from src file: %s\n", argv[1]);
    return EXIT_FAILURE;
  }

  // close files once done with them 
  fclose(input);
  fclose(output);

  return EXIT_SUCCESS;
}
