#include "friends.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

/*
 * Create a new user with the given name.  Insert it at the tail of the list
 * of users whose head is pointed to by *user_ptr_add.
 *
 * Return:
 *   - 0 if successful
 *   - 1 if a user by this name already exists in this list
 *   - 2 if the given name cannot fit in the 'name' array
 *       (don't forget about the null terminator)
 */
int create_user(const char *name, User **user_ptr_add) {
	if (strlen(name) > (MAX_NAME - 1)){
		return 2;
	}

	else if (*user_ptr_add == NULL){
		*user_ptr_add = malloc(sizeof(User));
		strncpy((*user_ptr_add)->name, name, (MAX_NAME - 1));
		(*user_ptr_add)->name[(MAX_NAME - 1)] = '\0';
		(*user_ptr_add)->next = NULL;
		(*user_ptr_add)->profile_pic[0] = '\0';
		return 0;
	}

	else{
		User *p = malloc(sizeof(User));
		strncpy(p->name, name, (MAX_NAME - 1));
		p->name[(MAX_NAME - 1)] = '\0';
		p->next = NULL;
		(*user_ptr_add)->profile_pic[0] = '\0';
		User *curr = *user_ptr_add;
		while (curr->next != NULL){
			if (strcmp(curr->name, name) == 0){
				return 1;
			}
			curr = curr->next;
		}
		curr->next = p;
		return 0;
	}
	return -1;
}


/*
 * Return a pointer to the user with this name in
 * the list starting with head. Return NULL if no such user exists.
 *
 * NOTE: You'll likely need to cast a (const User *) to a (User *)
 * to satisfy the prototype without warnings.
 */
User *find_user(const char *name, const User *head) {
    User *curr = (User *) head;
    while (curr != NULL){
        if (strcmp(curr->name, name) == 0){
            return &(*curr);
        }
        curr = curr->next;
    }
    return NULL;
}


/*
 * Print the usernames of all users in the list starting at curr.
 * Names should be printed to standard output, one per line.
 */
void list_users(const User *curr) {
	printf("User List\n");
	if (curr != NULL){
		User *cur = (User *) curr;
		while (cur != NULL){
			printf("\t%s\n", cur->name);
			cur = cur->next;
		}
	}
}


/*
 * Change the filename for the profile pic of the given user.
 *
 * Return:
 *   - 0 on success.
 *   - 1 if the file does not exist or cannot be opened.
 *   - 2 if the filename is too long.
 */
int update_pic(User *user, const char *filename) {
	FILE *error = fopen(filename, "r");
	if (error == NULL){return 1;}
	else if (strlen(filename) > (MAX_NAME - 1)){fclose(error); return 2;}
	else{
		strncpy(user->profile_pic, filename, (MAX_NAME - 1));
		user->profile_pic[(MAX_NAME - 1)] = '\0';
		fclose(error);
		return 0;
	}
	fclose(error);
    return -1;
}


/*
 * Make two users friends with each other.  This is symmetric - a pointer to
 * each user must be stored in the 'friends' array of the other.
 *
 * New friends must be added in the first empty spot in the 'friends' array.
 *
 * Return:
 *   - 0 on success.
 *   - 1 if the two users are already friends.
 *   - 2 if the users are not already friends, but at least one already has
 *     MAX_FRIENDS friends.
 *   - 3 if the same user is passed in twice.
 *   - 4 if at least one user does not exist.
 *
 * Do not modify either user if the result is a failure.
 * NOTE: If multiple errors apply, return the *largest* error code that applies.
 */
int make_friends(const char *name1, const char *name2, User *head) {
    if (strcmp(name1, name2) == 0){return 3;}
	else if (find_user(name1, head) == NULL || find_user(name2, head) == NULL){return 4;}
	User *first = find_user(name1, head);
	User *second = find_user(name2, head);
	int i=0, j=0;
	int val = 0;
	while ((first->friends)[i] != NULL){
		if (strcmp(((first->friends)[i])->name, name2) == 0){val = 1;}
		i++;
	}
	while ((second->friends)[j] != NULL){
		if (strcmp(((second->friends)[j])->name, name1) == 0){val = 1;}
		j++;
	}
	if (val == 1){return 1;}
	else if ((i == (MAX_FRIENDS - 1)) || (j == (MAX_FRIENDS - 1))){return 2;}

	else {
		(first->friends)[i] = second;
		(second->friends)[j] = first;
		return 0;
	}
	
	return -1;
}


/*
 * Print a user profile.
 * For an example of the required output format, see the example output
 * linked from the handout.
 * Return:
 *   - 0 on success.
 *   - 1 if the user is NULL.
 */
int print_user(const User *user) {
    char *dashes = {"------------------------------------------"};
	if (user == NULL){return -1;}
	else{
		FILE *profile = fopen(user->profile_pic, "r");
		if (profile == NULL){
			printf("Name: %s\n%s\nFriends:\n", user->name, dashes);
			int i  = 0;
			while ((user->friends)[i] != NULL){printf("%s\n", (user->friends[i])->name); i++;}
			printf("%s\nPosts:\n", dashes);
			if (profile != NULL){fclose(profile);}
			return 0;
		}
		else {
			char line[1000];
			while (fgets(line, 1000, profile) != NULL){
				printf("%s", line);
			}
			printf("\n");
			printf("Name: %s\n%s\nFriends:\n", user->name, dashes);
			int i  = 0;
			while ((user->friends)[i] != NULL){printf("%s\n", (user->friends[i])->name); i++;}
			printf("%s\nPosts:\n", dashes);
			Post *curr = user->first_post;
			while (curr != NULL){
				printf("From: %s\nDate: %s\n\n%s\n", curr->author, ctime(curr->date), curr->contents);
				curr = curr->next;
				if (curr == NULL){printf("%s", dashes);}
				else{
					printf("\n===\n\n");
				}
			}
			if (profile != NULL){fclose(profile);}
			return 0;
		}
	}
}


/*
 * Make a new post from 'author' to the 'target' user,
 * containing the given contents, IF the users are friends.
 *
 * Insert the new post at the *front* of the user's list of posts.
 *
 * 'contents' is a pointer to heap-allocated memory - you do not need
 * to allocate more memory to store the contents of the post.
 *
 * Return:
 *   - 0 on success
 *   - 1 if users exist but are not friends
 *   - 2 if either User pointer is NULL
 */
int make_post(const User *author, User *target, char *contents) {
    
	if (author == NULL || target == NULL){return 2;}
	
	int i=0, j=0;
	int val = 0;
	while ((author->friends)[i] != NULL){
		if (strcmp(((author->friends)[i])->name, target->name) == 0){val = 1;}
		i++;
	}
	while ((target->friends)[j] != NULL){
		if (strcmp(((target->friends)[j])->name, author->name) == 0){val = 1;}
		j++;
	}
	if (val == 0){return 1;}

	else {
		Post *new_post = malloc(sizeof(Post));
        time_t seconds = time(&seconds);
        new_post->date = &seconds;
        new_post->contents = contents;
        strcpy(new_post->author, author->name);
		printf("%s", (target->first_post)->contents);
        new_post->next = target->first_post;
        target->first_post = &(*new_post);
		printf("%s", (target->first_post)->contents);
        return 0;
	}
	
	return -1;
}


/*
 * From the list pointed to by *user_ptr_del, delete the user
 * with the given name.
 * Remove the deleted user from any lists of friends.
 *
 * Return:
 *   - 0 on success.
 *   - 1 if a user with this name does not exist.
 */
int delete_user(const char *name, User **user_ptr_del) {
    return -1;
}

no segmentation fault in make_post