/**
 * Account data export
 * 
 * @author Pierre Hubert
 */

import { User } from "./User";
import { Post } from "./Post";
import { Comment } from "./Comment";
import { UserLike } from "./UserLike";
import { SurveyResponse } from "./SurveyResponse";
import { Movie } from "./Movie";
import { ConversationMessage } from "./ConversationMessage";
import { Conversation } from "./Conversation";
import { Friend } from "./Friend";
import { CommentsHelper } from "../helpers/CommentsHelper";

export interface AccountExportBuilder {
	userID: number;
	userInfo: User;
	postsList: Post[];
	comments: Comment[];
	likes: UserLike[];
	surveyResponses: SurveyResponse[];
	movies: Movie[];
	allConversationMessages: ConversationMessage[];
	conversations: Conversation[];
	conversationsMessages: Map<number, ConversationMessage[]>;
	friendsList: Friend[];
	groups: number[];
}

export class AccountExport implements AccountExportBuilder {
	userID: number;
	userInfo: User;
	postsList: Post[];
	comments: Comment[];
	likes: UserLike[];
	surveyResponses: SurveyResponse[];
	movies: Movie[];
	allConversationMessages: ConversationMessage[];
	conversations: Conversation[];
	conversationsMessages: Map<number, ConversationMessage[]>;
	friendsList: Friend[];
	groups: number[];

	public constructor(info: AccountExportBuilder) {
		for (const key in info) {
			if (info.hasOwnProperty(key))
				this[key] = info[key];
		}
	}

	/**
	 * Get the ID of all the related users
	 */
	public async getRelatedUsersID() : Promise<Set<number>> {
		const set = new Set<number>();

		// Own user
		set.add(this.userID);

		// Friends
		this.friendsList.forEach(f => set.add(f.friendID))

		// Posts
		for(const p of this.postsList) {
			set.add(p.userID);
			if(p.isUserPage) set.add(p.userPageID);

			// Process post comments
			(await CommentsHelper.Get(p.id)).forEach(c => set.add(c.userID))
		}

		// Comments
		this.comments.forEach(c => set.add(c.userID))

		// Conversation members
		this.conversations.forEach(c => c.members.forEach(id => set.add(id)))

		// Conversations messages
		this.conversationsMessages.forEach(c => c.forEach(m => set.add(m.userID)))

		return set;
	}
}