/*
 * Copyright ©2022 Hal Perkins.  All rights reserved.  Permission is
 * hereby granted to the teaching staff of University of Washington
 * CSE 333 for use solely during Spring Quarter 2022 for purposes of
 * the course.  No other use, copying, distribution, or modification
 * is permitted without prior written consent. Copyrights for
 * third-party components of this work must be honored.  Instructors
 * interested in reusing these course materials should contact the
 * author.
 *
 * Buggy code for CSE 333 Section 2
 * 1. Draw a memory diagram for the execution to identify errors.
 * 2. Use gdb and valgrind to identify sources of runtime, logical,
 *    and memory errors.
 * 3. Clean up the code style.
 */

#include <string.h>  // strncpy, strlen
#include <stdio.h>   // printf
#include <stdlib.h>  // malloc, EXIT_SUCCESS, NULL
#include <ctype.h>   // toupper

// A SimpleString stores a C-string and its current length
typedef struct simplestring_st {
  char* word;
  int   length;
} SimpleString;

// Capitalize the first letter in the word
void CapitalizeWord(SimpleString* ss_ptr);

// Allocate a new SimpleString on the heap initialized with word
// and return pointer to the new SimpleString in dest
void InitWord(char* word, SimpleString* dest);

// Return a new string with the characters in word in reverse order.
char* ReverseWord(char* word);

int main(int argc, char* argv[]) {
  char comp[] = "computer";
  SimpleString ss = {comp, strlen(comp)};
  SimpleString* ss_ptr = &ss;

  // expecting "1. computer, 8"
  printf("1. %s, %d\n", ss_ptr->word, ss_ptr->length);

  char cse[] = "cse333";
  InitWord(cse, ss_ptr);
  // expecting "2. cse333, 6"
  printf("2. %s, %d\n", ss_ptr->word, ss_ptr->length);

  CapitalizeWord(ss_ptr);
  // expecting "3. Cse333, 6"
  printf("3. %s, %d\n", ss_ptr->word, ss_ptr->length);

  char* reversed = ReverseWord(ss_ptr->word);

  InitWord(reversed, ss_ptr);
  // expecting "4. 333esC, 6"
  printf("4. %s, %d\n", ss_ptr->word, ss_ptr->length);

  return EXIT_SUCCESS;
}

void InitWord(char* word, SimpleString* dest) {
  dest = (SimpleString*) malloc(sizeof(SimpleString));
  dest->length = strlen(word);
  dest->word = (char*) malloc(sizeof(char) * (dest->length + 1));
  strncpy(dest->word, word, dest->length + 1);
}


void CapitalizeWord(SimpleString* ss_ptr) {
  ss_ptr->word[0] = toupper(ss_ptr->word[0]);
}

char* ReverseWord(char* word) {
  char* result = NULL;  // the reversed string
  int L, R;
  char ch;
  int strsize = strlen(word) + 1;

  // copy original string then reverse and return the copy
  strncpy(result, word, strsize);

  L = 0;
  R = strlen(result);
  while (L < R) {
    ch = result[L];
    result[L] = result[R];
    result[R] = ch;
    L++;
    R--;
  }

  return result;
}